📄 recpicbuffer.cpp
字号:
ErrVal
RecPicBuffer::store( RecPicBufUnit* pcRecPicBufUnit,
SliceHeader* pcSliceHeader,
PicBufferList& rcOutputList,
PicBufferList& rcUnusedList )
{
RNOK( xStorePicture( pcRecPicBufUnit, rcOutputList, rcUnusedList, pcSliceHeader, pcSliceHeader->getIdrFlag() ) );
if( pcRecPicBufUnit->isNeededForRef() )
{
m_uiLastRefFrameNum = pcRecPicBufUnit->getFrameNum();
}
return Err::m_nOK;
}
ErrVal
RecPicBuffer::getRefLists( RefFrameList& rcList0,
RefFrameList& rcList1,
SliceHeader& rcSliceHeader )
{
//===== clear lists =====
rcList0.reset();
rcList1.reset();
ROTRS( rcSliceHeader.isIntraSlice(), Err::m_nOK );
if( rcSliceHeader.isPSlice() )
{
RNOK( xInitRefListPSlice ( rcList0 ) );
RNOK( xRefListRemapping ( rcList0, LIST_0, &rcSliceHeader ) );
RNOK( xAdaptListSize ( rcList0, LIST_0, rcSliceHeader ) );
RNOK( xDumpRefList ( rcList0, LIST_0 ) );
}
else // rcSliceHeader.isBSlice()
{
RNOK( xInitRefListsBSlice ( rcList0, rcList1 ) );
RNOK( xRefListRemapping ( rcList0, LIST_0, &rcSliceHeader ) );
RNOK( xRefListRemapping ( rcList1, LIST_1, &rcSliceHeader ) );
RNOK( xAdaptListSize ( rcList0, LIST_0, rcSliceHeader ) );
RNOK( xAdaptListSize ( rcList1, LIST_1, rcSliceHeader ) );
RNOK( xDumpRefList ( rcList0, LIST_0 ) );
RNOK( xDumpRefList ( rcList1, LIST_1 ) );
}
return Err::m_nOK;
}
ErrVal
RecPicBuffer::xAdaptListSize( RefFrameList& rcList,
ListIdx eListIdx,
SliceHeader& rcSliceHeader )
{
UInt uiDefaultListSize = rcSliceHeader.getNumRefIdxActive( eListIdx );
UInt uiMaximumListSize = rcList.getActive();
UInt uiCurrentListSize = min( uiDefaultListSize, uiMaximumListSize );
//===== update slice header =====
rcList. setActive ( uiCurrentListSize );
rcSliceHeader.setNumRefIdxActive( eListIdx, uiCurrentListSize );
if( uiCurrentListSize != rcSliceHeader.getPPS().getNumRefIdxActive( eListIdx ) )
{
rcSliceHeader.setNumRefIdxActiveOverrideFlag( true );
}
return Err::m_nOK;
}
ErrVal
RecPicBuffer::xCreateData( UInt uiMaxFramesInDPB,
const SequenceParameterSet& rcSPS )
{
ROF( m_bInitDone );
RNOK( xDeleteData() );
while( uiMaxFramesInDPB-- )
{
RecPicBufUnit* pcRecPicBufUnit = 0;
RNOK( RecPicBufUnit::create( pcRecPicBufUnit, *m_pcYuvBufferCtrlFullPel, *m_pcYuvBufferCtrlHalfPel, rcSPS ) );
m_cFreeRecPicBufUnitList.push_back( pcRecPicBufUnit );
}
RNOK( RecPicBufUnit::create( m_pcCurrRecPicBufUnit, *m_pcYuvBufferCtrlFullPel, *m_pcYuvBufferCtrlHalfPel, rcSPS ) );
RNOK( m_pcCurrRecPicBufUnit->uninit() );
return Err::m_nOK;
}
ErrVal
RecPicBuffer::xDeleteData()
{
ROF( m_bInitDone );
m_cFreeRecPicBufUnitList += m_cUsedRecPicBufUnitList;
m_cUsedRecPicBufUnitList.clear();
while( m_cFreeRecPicBufUnitList.size() )
{
RecPicBufUnit* pcRecPicBufUnit = m_cFreeRecPicBufUnitList.popFront();
pcRecPicBufUnit->destroy();
}
if( m_pcCurrRecPicBufUnit )
{
m_pcCurrRecPicBufUnit->destroy();
m_pcCurrRecPicBufUnit = NULL;
}
return Err::m_nOK;
}
ErrVal
RecPicBuffer::xCheckMissingPics( SliceHeader* pcSliceHeader,
PicBufferList& rcOutputList,
PicBufferList& rcUnusedList )
{
ROTRS( pcSliceHeader->getIdrFlag(), Err::m_nOK );
ROTRS( ( ( m_uiLastRefFrameNum + 1 ) % m_uiMaxFrameNum ) == pcSliceHeader->getFrameNum(), Err::m_nOK );
UInt uiMissingFrames = pcSliceHeader->getFrameNum() - m_uiLastRefFrameNum - 1;
if( pcSliceHeader->getFrameNum() <= m_uiLastRefFrameNum )
{
uiMissingFrames += m_uiMaxFrameNum;
}
ROF( pcSliceHeader->getSPS().getGapsInFrameNumValueAllowedFlag());
for( UInt uiIndex = 1; uiIndex <= uiMissingFrames; uiIndex++ )
{
Bool bTreatAsIdr = ( m_cUsedRecPicBufUnitList.empty() );
Int iPoc = ( bTreatAsIdr ? 0 : m_cUsedRecPicBufUnitList.back()->getPoc() );
UInt uiFrameNum = ( m_uiLastRefFrameNum + uiIndex ) % m_uiMaxFrameNum;
RNOK( m_pcCurrRecPicBufUnit->initNonEx( iPoc, uiFrameNum ) );
RNOK( xStorePicture( m_pcCurrRecPicBufUnit, rcOutputList, rcUnusedList, pcSliceHeader, bTreatAsIdr ) );
}
m_uiLastRefFrameNum = ( m_uiLastRefFrameNum + uiMissingFrames ) % m_uiMaxFrameNum;
return Err::m_nOK;
}
ErrVal
RecPicBuffer::xStorePicture( RecPicBufUnit* pcRecPicBufUnit,
PicBufferList& rcOutputList,
PicBufferList& rcUnusedList,
SliceHeader* pcSliceHeader,
Bool bTreatAsIdr )
{
ROF( pcRecPicBufUnit == m_pcCurrRecPicBufUnit );
if( bTreatAsIdr )
{
RNOK( xClearOutputAll( rcOutputList, rcUnusedList ) );
m_cUsedRecPicBufUnitList.push_back( pcRecPicBufUnit );
}
else
{
m_cUsedRecPicBufUnitList.push_back( pcRecPicBufUnit );
RNOK( xUpdateMemory( pcSliceHeader ) );
RNOK( xOutput( rcOutputList, rcUnusedList ) );
}
RNOK( xDumpRecPicBuffer() );
m_pcCurrRecPicBufUnit = m_cFreeRecPicBufUnitList.popFront();
return Err::m_nOK;
}
ErrVal
RecPicBuffer::xOutput( PicBufferList& rcOutputList,
PicBufferList& rcUnusedList )
{
ROTRS( m_cFreeRecPicBufUnitList.size(), Err::m_nOK );
//===== smallest non-ref/output poc value =====
Int iMinOutputPoc = MSYS_INT_MAX;
RecPicBufUnit* pcElemToRemove = 0;
RecPicBufUnitList::iterator iter = m_cUsedRecPicBufUnitList.begin();
RecPicBufUnitList::iterator end = m_cUsedRecPicBufUnitList.end ();
for( ; iter != end; iter++ )
{
Bool bOutput = ( ! (*iter)->isOutputted() && (*iter)->isExisting() && ! (*iter)->isNeededForRef() );
if( bOutput && (*iter)->getPoc() < iMinOutputPoc )
{
iMinOutputPoc = (*iter)->getPoc();
pcElemToRemove = (*iter);
}
}
ROF( pcElemToRemove ); // error, nothing can be removed
//===== copy all output elements to temporary list =====
RecPicBufUnitList cOutputList;
Int iMaxPoc = iMinOutputPoc;
Int iMinPoc = MSYS_INT_MAX;
iter = m_cUsedRecPicBufUnitList.begin();
for( ; iter != end; iter++ )
{
Bool bOutput = ( (*iter)->getPoc() <= iMinOutputPoc && ! (*iter)->isOutputted() );
if( bOutput )
{
if( (*iter)->isExisting() )
{
cOutputList.push_back( *iter );
if( (*iter)->getPoc() < iMinPoc )
{
iMinPoc = (*iter)->getPoc();
}
}
else
{
RNOK( (*iter)->markOutputted() );
}
}
}
//===== real output =====
for( Int iPoc = iMinPoc; iPoc <= iMaxPoc; iPoc++ )
{
iter = cOutputList.begin();
end = cOutputList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->getPoc() == iPoc )
{
RecPicBufUnit* pcRecPicBufUnit = *iter;
cOutputList.remove( pcRecPicBufUnit );
PicBuffer* pcPicBuffer = pcRecPicBufUnit->getPicBuffer();
ROF( pcPicBuffer );
pcRecPicBufUnit->getRecFrame()->store( pcPicBuffer );
rcOutputList.push_back( pcPicBuffer );
rcUnusedList.push_back( pcPicBuffer );
pcRecPicBufUnit->markOutputted();
break; // only one picture per POC
}
}
}
ROT( cOutputList.size() );
//===== clear buffer ====
RNOK( xClearBuffer() );
//===== check =====
ROT( m_cFreeRecPicBufUnitList.empty() ); // this should never happen
return Err::m_nOK;
}
ErrVal
RecPicBuffer::xClearOutputAll( PicBufferList& rcOutputList,
PicBufferList& rcUnusedList )
{
//===== create output list =====
RecPicBufUnitList cOutputList;
Int iMinPoc = MSYS_INT_MAX;
Int iMaxPoc = MSYS_INT_MIN;
RecPicBufUnitList::iterator iter = m_cUsedRecPicBufUnitList.begin();
RecPicBufUnitList::iterator end = m_cUsedRecPicBufUnitList.end ();
for( ; iter != end; iter++ )
{
Bool bOutput = ( ! (*iter)->isOutputted() && (*iter)->isExisting() );
if( bOutput )
{
cOutputList.push_back( *iter );
if( (*iter)->getPoc() < iMinPoc ) iMinPoc = (*iter)->getPoc();
if( (*iter)->getPoc() > iMaxPoc ) iMaxPoc = (*iter)->getPoc();
}
}
//===== real output =====
for( Int iPoc = iMinPoc; iPoc <= iMaxPoc; iPoc++ )
{
iter = cOutputList.begin();
end = cOutputList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->getPoc() == iPoc )
{
RecPicBufUnit* pcRecPicBufUnit = *iter;
cOutputList.remove( pcRecPicBufUnit );
//--- output ---
PicBuffer* pcPicBuffer = pcRecPicBufUnit->getPicBuffer();
ROF( pcPicBuffer );
pcRecPicBufUnit->getRecFrame()->store( pcPicBuffer );
rcOutputList.push_back( pcPicBuffer );
rcUnusedList.push_back( pcPicBuffer );
break; // only one picture per poc
}
}
}
ROT( cOutputList.size() );
//===== uninit all elements and move to free list =====
while( m_cUsedRecPicBufUnitList.size() )
{
RecPicBufUnit* pcRecPicBufUnit = m_cUsedRecPicBufUnitList.popFront();
RNOK( pcRecPicBufUnit->uninit() );
m_cFreeRecPicBufUnitList.push_back( pcRecPicBufUnit );
}
return Err::m_nOK;
}
ErrVal
RecPicBuffer::xUpdateMemory( SliceHeader* pcSliceHeader )
{
ROTRS( pcSliceHeader && pcSliceHeader->getNalRefIdc() == NAL_REF_IDC_PRIORITY_LOWEST, Err::m_nOK );
if( pcSliceHeader && pcSliceHeader->getDecRefPicMarking().getAdaptiveRefPicMarkingModeFlag() )
{
RNOK( xMMCO( pcSliceHeader ) );
}
else
{
RNOK( xSlidingWindow() );
}
//===== clear buffer -> remove non-ref pictures =====
RNOK( xClearBuffer() );
return Err::m_nOK;
}
ErrVal
RecPicBuffer::xClearBuffer()
{
//===== remove non-output / non-ref pictures =====
//--- store in temporary list ---
RecPicBufUnitList cTempList;
RecPicBufUnitList::iterator iter = m_cUsedRecPicBufUnitList.begin();
RecPicBufUnitList::iterator end = m_cUsedRecPicBufUnitList.end ();
for( ; iter != end; iter++ )
{
Bool bNoOutput = ( ! (*iter)->isExisting() || (*iter)->isOutputted() );
Bool bNonRef = ( ! (*iter)->isNeededForRef() );
if( bNonRef && bNoOutput )
{
cTempList.push_back( *iter );
}
}
//--- uninit and move to free list ---
while( cTempList.size() )
{
RecPicBufUnit* pcRecPicBufUnit = cTempList.popFront();
RNOK( pcRecPicBufUnit->uninit() );
m_cUsedRecPicBufUnitList.remove ( pcRecPicBufUnit );
m_cFreeRecPicBufUnitList.push_back( pcRecPicBufUnit );
}
return Err::m_nOK;
}
ErrVal
RecPicBuffer::xMMCO( SliceHeader* pcSliceHeader )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -