📄 mctf.cpp
字号:
if( bHalfPel )
{
RNOK( xFillAndUpsampleFrame ( pcFrame ) );
}
else
{
RNOK( xFillAndExtendFrame ( pcFrame ) );
}
}
RNOK( rcRefList0.add( pcFrame ) );
uiList0Size--;
}
ROT( uiList0Size );
}
//===== list 1 =====
{
Int iFrameId;
for( iFrameId = Int( uiFrame + 1 ); iFrameId <= (Int)( m_uiGOPSize >> uiBaseLevel ) && uiList1Size; iFrameId += 2 )
{
IntFrame* pcFrame = m_papcFrame[ iFrameId << uiBaseLevel ];
if( ! pcFrame->isExtended() )
{
if( bHalfPel )
{
RNOK( xFillAndUpsampleFrame ( pcFrame ) );
}
else
{
RNOK( xFillAndExtendFrame ( pcFrame ) );
}
}
RNOK( rcRefList1.add( pcFrame ) );
uiList1Size--;
}
ROT( uiList1Size );
}
return Err::m_nOK;
}
ErrVal
MCTF::xGetUpdateLists( RefFrameList& rcRefList0,
RefFrameList& rcRefList1,
CtrlDataList& rcCtrlList0,
CtrlDataList& rcCtrlList1,
UInt uiBaseLevel,
UInt uiFrame )
{
rcRefList0 .reset();
rcRefList1 .reset();
rcCtrlList0 .reset();
rcCtrlList1 .reset();
UInt uiFrameIdInGOP = ( uiFrame << uiBaseLevel );
SliceHeader* pcSliceHeader = m_pacControlData[uiFrameIdInGOP].getSliceHeader();
UInt uiUpdateLevel = m_uiDecompositionStages - uiBaseLevel - 1;
UInt uiList0Size = pcSliceHeader->getNumRefIdxUpdate( uiUpdateLevel, LIST_0 );
UInt uiList1Size = pcSliceHeader->getNumRefIdxUpdate( uiUpdateLevel, LIST_1 );
//===== list 0 =====
{
for( Int iFrameId = Int( uiFrame - 1 ); iFrameId >= 0 && uiList0Size; iFrameId -= 2 )
{
IntFrame* pcFrame = m_papcResidual [ iFrameId << uiBaseLevel ];
ControlData* pcControlData = &m_pacControlData [ iFrameId << uiBaseLevel ];
if( ! pcFrame->isExtended() )
{
RNOK( xFillAndExtendFrame( pcFrame ) );
}
RNOK( rcRefList0 .add( pcFrame ) );
RNOK( rcCtrlList0 .add( pcControlData ) );
uiList0Size--;
}
ROT( uiList0Size );
}
//===== list 1 =====
{
for( Int iFrameId = Int( uiFrame + 1 ); iFrameId <= (Int)( m_uiGOPSize >> uiBaseLevel ) && uiList1Size; iFrameId += 2 )
{
IntFrame* pcFrame = m_papcResidual [ iFrameId << uiBaseLevel ];
ControlData* pcControlData = &m_pacControlData [ iFrameId << uiBaseLevel ];
if( ! pcFrame->isExtended() )
{
RNOK( xFillAndExtendFrame( pcFrame ) );
}
RNOK( rcRefList1 .add( pcFrame ) );
RNOK( rcCtrlList1 .add( pcControlData ) );
uiList1Size--;
}
ROT( uiList1Size );
}
return Err::m_nOK;
}
ErrVal
MCTF::xInitControlDataMotion( UInt uiBaseLevel,
UInt uiFrame,
Bool bMotionEstimation )
{
UInt uiFrameIdInGOP = uiFrame << uiBaseLevel;
ControlData& rcControlData = m_pacControlData[uiFrameIdInGOP];
SliceHeader* pcSliceHeader = rcControlData.getSliceHeader ();
MbDataCtrl* pcMbDataCtrl = rcControlData.getMbDataCtrl ();
Double dScalFactor = rcControlData.getScalingFactor() * FACTOR_53_HP;
Double dQpPredData = m_adBaseQpLambdaMotion[ uiBaseLevel ] - 6.0 * log10( dScalFactor ) / log10( 2.0 );
Double dLambda = 0.85 * pow( 2.0, min( 52.0, dQpPredData ) / 3.0 - 4.0 );
Int iQp = max( MIN_QP, min( MAX_QP, (Int)floor( dQpPredData + 0.5 ) ) );
pcSliceHeader->setSliceHeaderQp( iQp );
rcControlData. setLambda ( dLambda );
if( bMotionEstimation )
{
RNOK( pcMbDataCtrl->initSlice( *pcSliceHeader, ENCODE_PROCESS, false, NULL ) );
}
return Err::m_nOK;
}
ErrVal
MCTF::xMotionEstimationStage( UInt uiBaseLevel )
{
for( UInt uiFrame = 1; uiFrame <= ( m_uiGOPSize >> uiBaseLevel ); uiFrame += 2 )
{
printf(".");
UInt uiFrameIdInGOP = uiFrame << uiBaseLevel;
ControlData& rcControlData = m_pacControlData[uiFrameIdInGOP];
IntFrame* pcFrame = m_papcFrame [uiFrameIdInGOP];
//===== get reference frame lists =====
RefFrameList& rcRefFrameList0 = rcControlData.getPrdFrameList( LIST_0 );
RefFrameList& rcRefFrameList1 = rcControlData.getPrdFrameList( LIST_1 );
RNOK( xGetPredictionLists ( rcRefFrameList0, rcRefFrameList1, uiBaseLevel, uiFrame, true ) );
RNOK( xInitControlDataMotion( uiBaseLevel, uiFrame, true ) );
RNOK( xMotionEstimation ( &rcRefFrameList0, &rcRefFrameList1, pcFrame, rcControlData ) );
}
RNOK( xClearBufferExtensions() );
return Err::m_nOK;
}
ErrVal
MCTF::xDecompositionStage( UInt uiBaseLevel )
{
//===== PREDICTION =====
for( UInt uiFramePrd = 1; uiFramePrd <= ( m_uiGOPSize >> uiBaseLevel ); uiFramePrd += 2 )
{
UInt uiFrameIdInGOP = uiFramePrd << uiBaseLevel;
ControlData& rcControlData = m_pacControlData[uiFrameIdInGOP];
IntFrame* pcFrame = m_papcFrame [uiFrameIdInGOP];
IntFrame* pcResidual = m_papcResidual [uiFrameIdInGOP];
IntFrame* pcMCFrame = m_pcFrameTemp;
RefFrameList& rcRefFrameList0 = rcControlData.getPrdFrameList( LIST_0 );
RefFrameList& rcRefFrameList1 = rcControlData.getPrdFrameList( LIST_1 );
RNOK( xGetPredictionLists ( rcRefFrameList0, rcRefFrameList1, uiBaseLevel, uiFramePrd, false ) );
RNOK( xInitControlDataMotion( uiBaseLevel, uiFramePrd, false ) );
RNOK( xMotionCompensation ( pcMCFrame, &rcRefFrameList0, &rcRefFrameList1,
rcControlData.getMbDataCtrl(), *rcControlData.getSliceHeader() ) );
RNOK( pcFrame ->prediction ( pcMCFrame, pcFrame ) );
RNOK( pcResidual->copy ( pcFrame ) );
RNOK( xZeroIntraMacroblocks ( pcResidual, rcControlData ) );
}
RNOK ( xClearBufferExtensions() );
//===== UPDATE =====
for( UInt uiFrameUpd = 2; uiFrameUpd <= ( m_uiGOPSize >> uiBaseLevel ); uiFrameUpd += 2 )
{
UInt uiFrameIdInGOP = uiFrameUpd << uiBaseLevel;
IntFrame* pcFrame = m_papcFrame [uiFrameIdInGOP];
RefFrameList acRefFrameListUpd[2];
CtrlDataList acCtrlDataList[2];
RNOK( xGetUpdateLists ( acRefFrameListUpd[0], acRefFrameListUpd[1],
acCtrlDataList[0], acCtrlDataList[1], uiBaseLevel, uiFrameUpd ) );
RNOK( xUpdateCompensation ( pcFrame, &acRefFrameListUpd[0], &acCtrlDataList[0], LIST_0 ) );
RNOK( xUpdateCompensation ( pcFrame, &acRefFrameListUpd[1], &acCtrlDataList[1], LIST_1 ) );
}
RNOK ( xClearBufferExtensions() );
return Err::m_nOK;
}
ErrVal
MCTF::xCompositionStage( UInt uiBaseLevel,
PicBufferList& rcPicBufferInputList )
{
//===== PREDICTION =====
for( UInt uiFramePrd = 1; uiFramePrd <= ( m_uiGOPSize >> uiBaseLevel ); uiFramePrd += 2 )
{
UInt uiFrameIdInGOP = uiFramePrd << uiBaseLevel;
ControlData& rcControlData = m_pacControlData[uiFrameIdInGOP];
IntFrame* pcFrame = m_papcFrame [uiFrameIdInGOP];
IntFrame* pcMCFrame = m_pcFrameTemp;
RefFrameList& rcRefFrameList0 = rcControlData.getPrdFrameList( LIST_0 );
RefFrameList& rcRefFrameList1 = rcControlData.getPrdFrameList( LIST_1 );
RNOK( xGetPredictionLists ( rcRefFrameList0, rcRefFrameList1,
uiBaseLevel, uiFramePrd, false ) );
RNOK( xMotionCompensation ( pcMCFrame, &rcRefFrameList0, &rcRefFrameList1,
rcControlData.getMbDataCtrl(), *rcControlData.getSliceHeader() ) );
RNOK( pcFrame ->inversePrediction ( pcMCFrame, pcFrame ) );
}
RNOK( xClearBufferExtensions() );
return Err::m_nOK;
}
ErrVal
MCTF::xStoreReconstruction( PicBufferList& rcPicBufferOutputList )
{
PicBufferList::iterator cOutputIter = rcPicBufferOutputList.begin();
for( UInt uiIndex = (m_bFirstGOPCoded?1:0); uiIndex <= m_uiGOPSize; uiIndex++, cOutputIter++ )
{
RNOK( m_papcFrame[uiIndex]->store( *cOutputIter ) );
}
return Err::m_nOK;
}
ErrVal
MCTF::xProcessGOP( PicBufferList& rcPicBufferInputList,
PicBufferList& rcPicBufferOutputList,
PicBufferList& rcPicBufferUnusedList )
{
RNOK( xInitGOP( rcPicBufferInputList ) );
for( Int iLevel = 0; iLevel < (Int)m_uiDecompositionStages; iLevel++ )
{
RNOK( xMotionEstimationStage ( iLevel ) );
RNOK( xDecompositionStage ( iLevel ) );
RNOK( xSetScalingFactors ( iLevel ) );
}
UInt uiStage = m_uiDecompositionStages;
while( uiStage-- > 0 )
{
RNOK( xCompositionStage( uiStage, rcPicBufferInputList ) );
}
RNOK( xStoreReconstruction( rcPicBufferOutputList ) );
RNOK( xFinishGOP ( rcPicBufferInputList,
rcPicBufferOutputList,
rcPicBufferUnusedList ) );
return Err::m_nOK;
}
ErrVal
MCTF::xFinishGOP( PicBufferList& rcPicBufferInputList,
PicBufferList& rcPicBufferOutputList,
PicBufferList& rcPicBufferUnusedList )
{
while( rcPicBufferOutputList.size() > m_uiGOPSize + ( m_bFirstGOPCoded ? 0 : 1 ) )
{
PicBuffer* pcPicBuffer = rcPicBufferOutputList.popBack();
rcPicBufferUnusedList.push_back( pcPicBuffer );
}
m_bFirstGOPCoded = true;
return Err::m_nOK;
}
ErrVal
MCTF::xUpdateCompensation( IntFrame* pcMCFrame,
RefFrameList* pcRefFrameList,
CtrlDataList* pcCtrlDataList,
ListIdx eListUpd)
{
ROFRS( pcCtrlDataList->getActive(), Err::m_nOK );
ListIdx eListPrd = ListIdx( 1-eListUpd );
for( Int iRefIdx = 1; iRefIdx <= (Int)pcCtrlDataList->getActive(); iRefIdx++ )
{
for( UInt uiMbIndex = 0; uiMbIndex < m_uiMbNumber; uiMbIndex++ )
{
UInt uiMbY = uiMbIndex / m_uiFrameWidthInMb;
UInt uiMbX = uiMbIndex % m_uiFrameWidthInMb;
MbDataCtrl* pcMbDataCtrlPrd = (*pcCtrlDataList)[ iRefIdx ]->getMbDataCtrl();
MbDataAccess* pcMbDataAccess = 0;
RNOK( pcMbDataCtrlPrd ->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->compensateUpdate ( *pcMbDataAccess, pcMCFrame,
iRefIdx, eListPrd, (*pcRefFrameList)[ iRefIdx ] ) );
}
}
return Err::m_nOK;
}
ErrVal
MCTF::process( PicBuffer* pcOrgPicBuffer,
PicBuffer* pcRecPicBuffer,
PicBufferList& rcPicBufferOutputList,
PicBufferList& rcPicBufferUnusedList )
{
if( pcOrgPicBuffer == NULL )
{
//===== finish =====
if( pcRecPicBuffer )
{
rcPicBufferUnusedList.push_back( pcRecPicBuffer );
}
if( m_cOrgPicBufferList.size() )
{
RNOK( xProcessGOP( m_cOrgPicBufferList, m_cRecPicBufferList, rcPicBufferUnusedList ) );
rcPicBufferOutputList += m_cRecPicBufferList;
}
rcPicBufferUnusedList += m_cOrgPicBufferList;
rcPicBufferUnusedList += m_cRecPicBufferList;
m_cOrgPicBufferList.clear();
m_cRecPicBufferList.clear();
return Err::m_nOK;
}
//===== insert buffers =====
m_cOrgPicBufferList.push_back( pcOrgPicBuffer );
m_cRecPicBufferList.push_back( pcRecPicBuffer );
UInt uiTargetBufferSize = ( 1 << m_uiDecompositionStages ) + ( m_bFirstGOPCoded ? 0 : 1 );
ROT( m_cOrgPicBufferList.size() > uiTargetBufferSize );
if( m_cOrgPicBufferList.size() == uiTargetBufferSize )
{
RNOK( xProcessGOP( m_cOrgPicBufferList, m_cRecPicBufferList, rcPicBufferUnusedList ) );
rcPicBufferOutputList += m_cRecPicBufferList;
rcPicBufferUnusedList += m_cOrgPicBufferList;
rcPicBufferUnusedList += m_cRecPicBufferList;
m_cOrgPicBufferList.clear();
m_cRecPicBufferList.clear();
}
return Err::m_nOK;
}
H264AVC_NAMESPACE_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -