framemng.cpp
来自「JMVM MPEG MVC/3DAV 测试平台 国际通用标准」· C++ 代码 · 共 1,500 行 · 第 1/3 页
CPP
1,500 行
RNOK( m_cFrameUnitBuffer.getFrameUnit( m_pcCurrentFrameUnit ) );
RNOK( m_pcCurrentFrameUnit->init( rcSH, pcPicBuffer ) );
m_pcCurrentFrameUnit->getFrame().setViewId( rcSH.getViewId() );
m_pcCurrentFrameUnit->getFrame().setInterViewFlag(rcSH.getInterViewFlag()); //JVT-W056
rcSH.setFrameUnit( m_pcCurrentFrameUnit );
return Err::m_nOK;
}
ErrVal FrameMng::xCheckMissingFrameNums( SliceHeader& rcSH )
{
//===== check frame numbers for reference pictures =====
if( ( ( m_uiPrecedingRefFrameNum + 1 ) % m_uiMaxFrameNumCurr) != rcSH.getFrameNum() &&
(m_uiLastViewId == rcSH.getViewId()) )
{
UInt uiNumMissingPictures = rcSH.getFrameNum() - m_uiPrecedingRefFrameNum - 1;
if( rcSH.getFrameNum() <= m_uiPrecedingRefFrameNum )
{
uiNumMissingPictures += m_uiMaxFrameNumCurr;
}
if( rcSH.getSPS().getRequiredFrameNumUpdateBehaviourFlag() )
{
for( UInt uiIndex = 1; uiIndex <= uiNumMissingPictures; uiIndex++ )
{
UInt uiFrameNum = ( m_uiPrecedingRefFrameNum + uiIndex ) % m_uiMaxFrameNumCurr;
FrameUnit* pcFrameUnit = 0;
RNOK( m_cFrameUnitBuffer.getFrameUnit( pcFrameUnit ) );
//JVT-S036 {
if( !m_pcCurrentFrameUnit->getBaseRep() )
{
FUList::iterator iter = m_cShortTermList.begin();
FUList::iterator end = m_cShortTermList.end();
Bool bFlag = false;
for( ; iter != m_cShortTermList.end(); iter++ )
{
if( (*iter)->getBaseRep() && (*iter)->getFrameNumber() == m_pcCurrentFrameUnit->getFrameNumber())
{
bFlag = true;
break;
}
}
if( bFlag )
{
FrameUnit* pcFrameUnitTemp = (*iter);
RNOK(pcFrameUnit->init( rcSH, *pcFrameUnitTemp ));
}
else
{
RNOK( pcFrameUnit->init( rcSH, *m_pcCurrentFrameUnit ) );
}
}
else
//JVT-S036 }
{
RNOK( pcFrameUnit->init( rcSH, *m_pcCurrentFrameUnit ) ); // HS: decoder robustness
}
pcFrameUnit->setFrameNumber( uiFrameNum );
m_cShortTermList.push_front( pcFrameUnit );
m_iEntriesInDPB++;
RNOK( xSlidingWindowUpdate() );
}
}
else
{
printf("\n LOST PICTURES: %d\n", uiNumMissingPictures );
AF();
}
m_uiPrecedingRefFrameNum = ( m_uiPrecedingRefFrameNum + uiNumMissingPictures ) % m_uiMaxFrameNumCurr;
}
return Err::m_nOK;
}
ErrVal FrameMng::setPicBufferLists( PicBufferList& rcPicBufferOutputList, PicBufferList& rcPicBufferUnusedList )
{
rcPicBufferUnusedList += m_cPicBufferUnusedList;
m_cPicBufferUnusedList.clear();
rcPicBufferOutputList += m_cPicBufferOutputList;
m_cPicBufferOutputList.clear();
return Err::m_nOK;
}
ErrVal FrameMng::storePicture( const SliceHeader& rcSH )
{
//===== memory managment =====
if( rcSH.isIdrNalUnit() )
{
RNOK( xClearListsIDR( rcSH ) );
}
RNOK( xManageMemory( rcSH ) );
//===== store current picture =====
RNOK( xStoreCurrentPicture( rcSH ) );
//===== set pictures for output =====
RNOK( xSetOutputListMVC( m_pcCurrentFrameUnit, rcSH.getSPS().getSpsMVC()->getNumViewMinus1()+1) );
if( rcSH.getNalRefIdc() )
{
m_uiPrecedingRefFrameNum = m_pcCurrentFrameUnit->getFrameNumber();
}
return Err::m_nOK;
}
UInt FrameMng::xSortPocOrderedList()
{
UInt uiFirstPosWithGreaterPoc;
Int iCurrPoc = m_pcCurrentFrameUnit->getFrame().getPOC();
std::sort( m_cPocOrderedFrameList.begin(), m_cPocOrderedFrameList.end(), PocOrder() );
for( uiFirstPosWithGreaterPoc = 0; uiFirstPosWithGreaterPoc < m_cPocOrderedFrameList.size(); uiFirstPosWithGreaterPoc++ )
{
if( m_cPocOrderedFrameList.get( uiFirstPosWithGreaterPoc )->getPOC() > iCurrPoc )
{
break;
}
}
return uiFirstPosWithGreaterPoc;
}
ErrVal FrameMng::xSetInitialReferenceListPFrame( SliceHeader& rcSH )
{
RefPicList<RefPic>& rcList = rcSH.getRefPicList( LIST_0 );
/*
if( ! rcSH.getKeyPictureFlag() )
m_cShortTermList.setRefPicListFGS( rcList, rcSH );
else
*/
m_cShortTermList.setRefPicList( rcList, rcSH);
return Err::m_nOK;
}
ErrVal FrameMng::xSetInitialReferenceListBFrame( SliceHeader& rcSH )
{
RefPicList<RefPic>& rcList0 = rcSH.getRefPicList( LIST_0 );
RefPicList<RefPic>& rcList1 = rcSH.getRefPicList( LIST_1 );
UInt uiFirstPosWithGreaterPoc, uiPos;
FUIter iter;
//====== set Poc ordered short-term list and get index with smallest Poc greater than current ======
m_cPocOrderedFrameList.reset();
/*
if( ! rcSH.getKeyPictureFlag() )
m_cShortTermList.setRefFrameListFGS( m_cPocOrderedFrameList, rcSH );
else
*/
m_cShortTermList.setRefFrameList( m_cPocOrderedFrameList , rcSH);
uiFirstPosWithGreaterPoc = xSortPocOrderedList();
//===== set short term reference frames =====
for( uiPos = uiFirstPosWithGreaterPoc - 1; uiPos != MSYS_UINT_MAX; uiPos-- )
{
rcList0.next().setFrame( m_cPocOrderedFrameList.get( uiPos ) );
}
for( uiPos = uiFirstPosWithGreaterPoc; uiPos != m_cPocOrderedFrameList.size(); uiPos++ )
{
rcList0.next().setFrame( m_cPocOrderedFrameList.get( uiPos ) );
rcList1.next().setFrame( m_cPocOrderedFrameList.get( uiPos ) );
}
for( uiPos = uiFirstPosWithGreaterPoc - 1; uiPos != MSYS_UINT_MAX; uiPos-- )
{
rcList1.next().setFrame( m_cPocOrderedFrameList.get( uiPos ) );
}
return Err::m_nOK;
}
ErrVal FrameMng::setRefPicLists( SliceHeader& rcSH, Bool bDoNotRemap )
{
RNOK( xSetReferenceLists( rcSH) );
if(rcSH.getNalUnitType() == NAL_UNIT_CODED_SLICE_SCALABLE)
xSetReferenceListsMVC( rcSH );
if( ! bDoNotRemap )
{
//===== remapping =====
RNOK( xReferenceListRemapping( rcSH, LIST_0 ) );
RNOK( xReferenceListRemapping( rcSH, LIST_1 ) );
}
// cleanup //dump
#if 0
if( rcSH.isInterP() )
{
xDumpRefList( LIST_0, rcSH );
}
else if (rcSH.isInterB())
{
xDumpRefList( LIST_0, rcSH );
xDumpRefList( LIST_1, rcSH );
}
#endif
return Err::m_nOK;
}
ErrVal FrameMng::xSetReferenceLists( SliceHeader& rcSH )
{
rcSH.getRefPicList( LIST_0 ).reset( 0 );
rcSH.getRefPicList( LIST_1 ).reset( 0 );
if( rcSH.isIntra() )
{
return Err::m_nOK;
}
rcSH.getRefPicList( LIST_0 ).reset();
if( rcSH.isInterB() )
{
rcSH.getRefPicList( LIST_1 ).reset();
}
if(rcSH.getNalUnitType() == NAL_UNIT_CODED_SLICE_SCALABLE)
{
if(rcSH.getAnchorPicFlag()) //no temporal pics
return Err::m_nOK;
}
//===== initial lists =====
if( ! rcSH.isInterB() )
{
RNOK( xSetInitialReferenceListPFrame( rcSH ) );
}
else
{
RNOK( xSetInitialReferenceListBFrame( rcSH ) );
}
// cleanup
return Err::m_nOK;
}
ErrVal FrameMng::xClearListsIDR( const SliceHeader& rcSH )
{
//===== output =====
for( FUIter iter = m_cOrderedPOCList.begin(); iter != m_cOrderedPOCList.end(); iter++ )
{
if(rcSH.getViewId() == (*iter)->getFrame().getViewId() )
{
if( ! rcSH.getNoOutputOfPriorPicsFlag() )
{
/* if( (*iter)->getFGSPicBuffer() )
{
(*iter)->getFGSPicBuffer()->setCts( (UInt64)((*iter)->getMaxPOC()) ); // HS: decoder robustness
m_cPicBufferOutputList.push_back( (*iter)->getFGSPicBuffer() );
}
else */
if ((*iter)->getPicBuffer() ) //JVT-S036
{
(*iter)->getPicBuffer()->setCts( (UInt64)((*iter)->getMaxPOC()) ); // HS: decoder robustness
m_cPicBufferOutputList.push_back( (*iter)->getPicBuffer() );
}
}
(*iter)->setOutputDone();
if( xFindAndErase( m_cNonRefList, *iter ) )
{
RNOK( xAddToFreeList( (*iter) ) );
}
m_cOrderedPOCList.erase((iter));
}
}
// m_cOrderedPOCList.clear();
return Err::m_nOK;
}
UInt FrameMng::MaxRefFrames( UInt uiLevel, UInt uiNumMbs )
{
return m_uiDBPMemory[ uiLevel ] / ( 384 * uiNumMbs );
}
ErrVal FrameMng::outputAll()
{
FUIter iter;
//===== output =====
for( iter = m_cOrderedPOCList.begin(); iter != m_cOrderedPOCList.end(); iter++ )
{
/* if( (*iter)->getFGSPicBuffer() )
{
(*iter)->getFGSPicBuffer()->setCts( (UInt64)((*iter)->getMaxPOC()) ); // HS: decoder robustness
m_cPicBufferOutputList.push_back( (*iter)->getFGSPicBuffer() );
}
else
*/
if ((*iter)->getPicBuffer() ) //JVT-S036
{
(*iter)->getPicBuffer()->setCts( (UInt64)((*iter)->getMaxPOC()) ); // HS: decoder robustness
m_cPicBufferOutputList.push_back( (*iter)->getPicBuffer() );
}
(*iter)->setOutputDone();
}
m_cOrderedPOCList.erase( m_cOrderedPOCList.begin(), iter );
RNOK( xAddToFreeList( m_cShortTermList ) );
RNOK( xAddToFreeList( m_cNonRefList ) );
return Err::m_nOK;
}
/*
ErrVal FrameMng::storeFGSPicture( PicBuffer* pcPicBuffer )
{
UInt uiFGSReconCount = m_pcCurrentFrameUnit->getFGSReconCount();
m_pcCurrentFrameUnit->getFGSReconstruction(uiFGSReconCount)->copyAll(m_pcCurrentFrameUnit->getFGSIntFrame());
m_pcCurrentFrameUnit->setFGSReconCount(uiFGSReconCount + 1);
m_pcCurrentFrameUnit->setFGS( pcPicBuffer );
m_pcCurrentFrameUnit->getFGSIntFrame()->store( pcPicBuffer );
m_pcCurrentFrameUnit->getFGSFrame().extendFrame( m_pcQuarterPelFilter );
return Err::m_nOK;
}
*/
ErrVal FrameMng::xStoreCurrentPicture( const SliceHeader& rcSH )
{
Frame& cBaseFrame = m_pcCurrentFrameUnit->getFrame();
PicBuffer cTempPicBuffer(cBaseFrame.getFullPelYuvBuffer()->getBuffer());
PicBuffer* pcTempPicBuffer = m_pcCurrentFrameUnit->getPicBuffer();
cBaseFrame.setViewId(rcSH.getViewId());
pcTempPicBuffer->setViewId(rcSH.getViewId());
m_uiLastViewId = rcSH.getViewId();
// Base layer
/*
m_pcCurrentFrameUnit->getFGSReconstruction(0)->load(& cTempPicBuffer);
m_pcCurrentFrameUnit->setFGSReconCount(1);
*/
RNOK( m_pcCurrentFrameUnit->getFrame().extendFrame( m_pcQuarterPelFilter ) );
if( rcSH.getNalRefIdc() )
{
//===== store as short term picture =====
m_pcCurrentFrameUnit->setFrameNumber( rcSH.getFrameNum() );
m_pcCurrentFrameUnit->setUsed ();
m_cShortTermList.push_front( m_pcCurrentFrameUnit );
m_iEntriesInDPB++;
//JVT-S036 start
if( rcSH.getKeyPicFlagScalable() )
{
RNOK( m_cFrameUnitBuffer.getFrameUnit( m_pcCurrentFrameUnitBase ) );
RNOK( m_pcCurrentFrameUnitBase->copyBase( rcSH, *m_pcCurrentFrameUnit ) );
m_pcCurrentFrameUnitBase->setBaseRep( true );
m_cShortTermList.push_front( m_pcCurrentFrameUnitBase );
m_iEntriesInDPB++;
}
//JVT-S036 end
}
else
{
m_cNonRefList.push_back( m_pcCurrentFrameUnit );
m_iEntriesInDPB++;
}
//===== store reference in ordered POC List =====
FUIter iter;
for( iter = m_cOrderedPOCList.begin(); iter != m_cOrderedPOCList.end(); iter++ )
{
if( (*iter)->getMaxPOC() > m_pcCurrentFrameUnit->getMaxPOC() )
{
break;
}
}
if( rcSH.getKeyPicFlagScalable() ) //JVT-S036
{
m_cOrderedPOCList.insert( iter, m_pcCurrentFrameUnitBase );
}
else
{
m_cOrderedPOCList.insert( iter, m_pcCurrentFrameUnit );
}
return Err::m_nOK;
}
ErrVal FrameMng::xMmcoMarkShortTermAsUnused( const FrameUnit* pcCurrFrameUnit, UInt uiDiffOfPicNums )
{
UInt uiCurrPicNum = pcCurrFrameUnit->getFrameNumber();
UInt uiPicNumN = uiCurrPicNum - uiDiffOfPicNums - 1;
if( uiCurrPicNum <= uiDiffOfPicNums )
{
uiPicNumN += m_uiMaxFrameNumPrev;
}
FUIter iter = m_cShortTermList.findShortTerm( uiPicNumN );
if( iter == m_cShortTermList.end() )
{
printf("\nMMCO not possible\n" );
return Err::m_nOK; // HS: decoder robustness
}
FrameUnit* pcFrameUnit = (*iter);
pcFrameUnit->setUnused();
RNOK( xRemoveFromRefList( m_cShortTermList, iter ) );
return Err::m_nOK;
}
//JVT-S036 start
ErrVal FrameMng::xMmcoMarkShortTermAsUnusedBase( const FrameUnit* pcCurrFrameUnit, UInt uiDiffOfPicNums )
{
UInt uiCurrPicNum = pcCurrFrameUnit->getFrameNumber();
UInt uiPicNumN = uiCurrPicNum - uiDiffOfPicNums - 1;
if( uiCurrPicNum <= uiDiffOfPicNums )
{
uiPicNumN += m_uiMaxFrameNumPrev;
}
FUIter iter = m_cShortTermList.findShortTerm( uiPicNumN );
if( iter == m_cShortTermList.end() )
{
printf("\nMMCO not possible\n" );
return Err::m_nOK; // HS: decoder robustness
}
FrameUnit* pcFrameUnit = (*iter);
if(pcFrameUnit->getBaseRep() )
{
pcFrameUnit->setUnused();
RNOK( xRemoveFromRefList( m_cShortTermList, iter ) );
}
return Err::m_nOK;
}
//JVT-S036 end
ErrVal FrameMng::xManageMemory( const SliceHeader& rcSH )
{
ROTRS( ! rcSH.getNalRefIdc(), Err::m_nOK );
if( ! rcSH.getAdaptiveRefPicBufferingFlag() )
{
RNOK( xSlidingWindowUpdate() );
return Err::m_nOK;
}
MmcoOp eMmcoOp;
const MmcoBuffer& rcMmcoBuffer = rcSH.getMmcoBuffer();
UInt uiVal1, uiVal2;
Int iIndex = 0;
while( MMCO_END != (eMmcoOp = rcMmcoBuffer.get( iIndex++ ).getCommand( uiVal1, uiVal2)) )
{
switch (eMmcoOp)
{
case MMCO_SHORT_TERM_UNUSED:
RNOK( xMmcoMarkShortTermAsUnusedMVC( m_pcCurrentFrameUnit, uiVal1, rcSH.getViewId() ) );
break;
case MMCO_RESET:
case MMCO_MAX_LONG_TERM_IDX:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?