📄 recpicbuffer.cpp
字号:
ROF( pcSliceHeader );
Mmco eMmcoOp;
const DecRefPicMarking& rcMmcoBuffer = pcSliceHeader->getDecRefPicMarking();
Int iIndex = 0;
UInt uiVal1, uiVal2;
while( MMCO_END != ( eMmcoOp = rcMmcoBuffer.get( iIndex++ ).getCommand( uiVal1, uiVal2 ) ) )
{
switch( eMmcoOp )
{
case MMCO_SHORT_TERM_UNUSED:
RNOK( xMarkShortTermUnused( m_pcCurrRecPicBufUnit, uiVal1 ) );
break;
case MMCO_RESET:
case MMCO_MAX_LONG_TERM_IDX:
case MMCO_ASSIGN_LONG_TERM:
case MMCO_LONG_TERM_UNUSED:
case MMCO_SET_LONG_TERM:
default:
RERR();
}
}
return Err::m_nOK;
}
ErrVal
RecPicBuffer::xMarkShortTermUnused( RecPicBufUnit* pcCurrentRecPicBufUnit,
UInt uiDiffOfPicNums )
{
ROF( pcCurrentRecPicBufUnit );
UInt uiCurrPicNum = pcCurrentRecPicBufUnit->getFrameNum();
Int iPicNumN = (Int)uiCurrPicNum - (Int)uiDiffOfPicNums - 1;
RecPicBufUnitList::iterator iter = m_cUsedRecPicBufUnitList.begin();
RecPicBufUnitList::iterator end = m_cUsedRecPicBufUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() && (*iter)->getPicNum( uiCurrPicNum, m_uiMaxFrameNum ) == iPicNumN )
{
(*iter)->markNonRef();
return Err::m_nOK;
}
}
RERR();
}
ErrVal
RecPicBuffer::xSlidingWindow()
{
//===== get number of reference frames =====
UInt uiCurrNumRefFrames = 0;
RecPicBufUnitList::iterator iter = m_cUsedRecPicBufUnitList.begin();
RecPicBufUnitList::iterator end = m_cUsedRecPicBufUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() )
{
uiCurrNumRefFrames++;
}
}
ROTRS( uiCurrNumRefFrames <= m_uiNumRefFrames, Err::m_nOK );
//===== sliding window reference picture update =====
//--- look for last ref frame that shall be removed ---
UInt uiRefFramesToRemove = uiCurrNumRefFrames - m_uiNumRefFrames;
iter = m_cUsedRecPicBufUnitList.begin();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() )
{
uiRefFramesToRemove--;
if( uiRefFramesToRemove == 0 )
{
break;
}
}
}
ROT( uiRefFramesToRemove );
//--- delete reference label ---
end = ++iter;
iter = m_cUsedRecPicBufUnitList.begin();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() )
{
RNOK( (*iter)->markNonRef() );
}
}
return Err::m_nOK;
}
ErrVal
RecPicBuffer::xDumpRecPicBuffer()
{
#if 1 // NO_DEBUG
return Err::m_nOK;
#endif
printf( "\nRECONSTRUCTED PICTURE BUFFER:\n" );
RecPicBufUnitList::iterator iter = m_cUsedRecPicBufUnitList.begin();
RecPicBufUnitList::iterator end = m_cUsedRecPicBufUnitList.end ();
for( Int iIndex = 0; iter != end; iter++ )
{
RecPicBufUnit* p = (*iter);
printf( "\tPOS=%d:\tFN=%d\tPoc=%d\t%s\t", iIndex, p->getFrameNum(), p->getPoc(), (p->isNeededForRef()?"REF":" ") );
if( p->isOutputted() ) printf("Outputted ");
if( !p->isExisting () ) printf("NotExisting ");
printf("\n");
}
printf("\n");
return Err::m_nOK;
}
ErrVal
RecPicBuffer::xInitRefListPSlice( RefFrameList& rcList )
{
//----- get current frame num -----
UInt uiCurrFrameNum = m_pcCurrRecPicBufUnit->getFrameNum();
//----- generate decreasing POC list -----
for( Int iMaxPicNum = (Int)uiCurrFrameNum; true; )
{
RecPicBufUnit* pNext = 0;
RecPicBufUnitList::iterator iter = m_cUsedRecPicBufUnitList.begin();
RecPicBufUnitList::iterator end = m_cUsedRecPicBufUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() &&
(*iter)->getPicNum( uiCurrFrameNum, m_uiMaxFrameNum ) < iMaxPicNum &&
( ! pNext ||
(*iter)->getPicNum( uiCurrFrameNum, m_uiMaxFrameNum ) > pNext->getPicNum( uiCurrFrameNum, m_uiMaxFrameNum ) ) )
{
pNext = (*iter);
}
}
if( ! pNext )
{
break;
}
iMaxPicNum = pNext->getPicNum( uiCurrFrameNum, m_uiMaxFrameNum );
rcList.add( pNext->getRecFrame() );
}
return Err::m_nOK;
}
ErrVal
RecPicBuffer::xInitRefListsBSlice( RefFrameList& rcList0,
RefFrameList& rcList1 )
{
RefFrameList cDecreasingPocList;
RefFrameList cIncreasingPocList;
Int iCurrPoc = m_pcCurrRecPicBufUnit->getPoc();
//----- generate decreasing Poc list -----
for( Int iMaxPoc = iCurrPoc; true; )
{
RecPicBufUnit* pNext = 0;
RecPicBufUnitList::iterator iter = m_cUsedRecPicBufUnitList.begin();
RecPicBufUnitList::iterator end = m_cUsedRecPicBufUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() &&
(*iter)->getPoc() < iMaxPoc &&
( ! pNext ||
(*iter)->getPoc() > pNext->getPoc() ) )
{
pNext = (*iter);
}
}
if( ! pNext )
{
break;
}
iMaxPoc = pNext->getPoc();
cDecreasingPocList.add( pNext->getRecFrame() );
}
//----- generate increasing Poc list -----
for( Int iMinPoc = iCurrPoc; true; )
{
RecPicBufUnit* pNext = 0;
RecPicBufUnitList::iterator iter = m_cUsedRecPicBufUnitList.begin();
RecPicBufUnitList::iterator end = m_cUsedRecPicBufUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() &&
(*iter)->getPoc() > iMinPoc &&
( ! pNext ||
(*iter)->getPoc() < pNext->getPoc() ) )
{
pNext = (*iter);
}
}
if( ! pNext )
{
break;
}
iMinPoc = pNext->getPoc();
cIncreasingPocList.add( pNext->getRecFrame() );
}
//----- list 0 and list 1 -----
UInt uiPos;
for( uiPos = 0; uiPos < cDecreasingPocList.getSize(); uiPos++ )
{
RNOK( rcList0.add( cDecreasingPocList.getEntry( uiPos ) ) );
}
for( uiPos = 0; uiPos < cIncreasingPocList.getSize(); uiPos++ )
{
RNOK( rcList0.add( cIncreasingPocList.getEntry( uiPos ) ) );
RNOK( rcList1.add( cIncreasingPocList.getEntry( uiPos ) ) );
}
for( uiPos = 0; uiPos < cDecreasingPocList.getSize(); uiPos++ )
{
RNOK( rcList1.add( cDecreasingPocList.getEntry( uiPos ) ) );
}
//----- check for element switching -----
if( rcList1.getActive() >= 2 && rcList0.getActive() == rcList1.getActive() )
{
Bool bSwitch = true;
for( uiPos = 0; uiPos < rcList1.getActive(); uiPos++ )
{
if( rcList0.getEntry( uiPos ) != rcList1.getEntry( uiPos ) )
{
bSwitch = false;
break;
}
}
if( bSwitch )
{
rcList1.switchFirst();
}
}
return Err::m_nOK;
}
ErrVal
RecPicBuffer::xRefListRemapping( RefFrameList& rcList,
ListIdx eListIdx,
SliceHeader* pcSliceHeader )
{
ROF( pcSliceHeader );
const RefPicListReOrdering& rcRplrBuffer = pcSliceHeader->getRefPicListReordering( eListIdx );
//===== re-ordering ======
if( rcRplrBuffer.getRefPicListReorderingFlag() )
{
UInt uiPicNumPred = pcSliceHeader->getFrameNum();
UInt uiIndex = 0;
UInt uiCommand = 0;
UInt uiIdentifier = 0;
while( RPLR_END != ( uiCommand = rcRplrBuffer.get( uiIndex ).getCommand( uiIdentifier ) ) )
{
Frame* pcFrame = 0;
if( uiCommand == RPLR_LONG )
{
//===== long-term index =====
RERR(); // long-term not supported
}
else
{
//===== short-term index =====
UInt uiAbsDiff = uiIdentifier + 1;
//----- set short-term index (pic num) -----
if( uiCommand == RPLR_NEG )
{
if( uiPicNumPred < uiAbsDiff )
{
uiPicNumPred -= ( uiAbsDiff - m_uiMaxFrameNum );
}
else
{
uiPicNumPred -= uiAbsDiff;
}
}
else // uiCommand == RPLR_POS
{
if( uiPicNumPred + uiAbsDiff > m_uiMaxFrameNum - 1 )
{
uiPicNumPred += ( uiAbsDiff - m_uiMaxFrameNum );
}
else
{
uiPicNumPred += uiAbsDiff;
}
}
uiIdentifier = uiPicNumPred;
//----- get frame -----
RecPicBufUnitList::iterator iter = m_cUsedRecPicBufUnitList.begin();
RecPicBufUnitList::iterator end = m_cUsedRecPicBufUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() &&
(*iter)->getFrameNum() == uiIdentifier )
{
pcFrame = (*iter)->getRecFrame();
break;
}
}
if( ! pcFrame )
{
fprintf( stderr, "\nERROR: MISSING PICTURE for RPLR\n\n" );
RERR();
}
//----- find picture in reference list -----
UInt uiRemoveIndex = MSYS_UINT_MAX;
for( UInt uiPos = uiIndex; uiPos < rcList.getActive(); uiPos++ ) // active is equal to size
{
if( rcList.getEntry( uiPos ) == pcFrame )
{
uiRemoveIndex = uiPos;
break;
}
}
//----- reference list re-ordering -----
RNOK( rcList.setElementAndRemove( uiIndex, uiRemoveIndex, pcFrame ) );
uiIndex++;
} // short-term
} // while
}
return Err::m_nOK;
}
ErrVal
RecPicBuffer::xDumpRefList( RefFrameList& rcList,
ListIdx eListIdx )
{
#if 1 // NO_DEBUG
return Err::m_nOK;
#endif
printf( "List %d =", eListIdx );
for( UInt uiIndex = 1; uiIndex <= rcList.getActive(); uiIndex++ )
{
printf( " %d", rcList[uiIndex]->getPoc() );
}
printf( "\n" );
return Err::m_nOK;
}
H264AVC_NAMESPACE_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -