📄 recpicbuffer.cpp
字号:
{
//===== clear lists =====
rcList0.reset();
rcList1.reset();
ROTRS( rcSliceHeader.isIntra(), Err::m_nOK );
if( rcSliceHeader.isInterP() )
{
RNOK( xInitRefListPSlice ( rcList0 ) );
AddMultiviewRef (m_cUsedRecPicBufUnitList, rcList0, rcSliceHeader.getNumRefIdxActive(LIST_0), FORWARD, rcSliceHeader);//JVT-W056 Samsung
RNOK( xRefListRemapping ( rcList0, LIST_0, &rcSliceHeader ) );
RNOK( xAdaptListSize ( rcList0, LIST_0, rcSliceHeader ) );
RNOK( xDumpRefList ( rcList0, LIST_0 ) );
}
else // rcSliceHeader.isInterB()
{
RNOK( xInitRefListsBSlice ( rcList0, rcList1 ) );
AddMultiviewRef(m_cUsedRecPicBufUnitList, rcList0, rcSliceHeader.getNumRefIdxActive(LIST_0), FORWARD, rcSliceHeader);//JVT-W056 Samsung
AddMultiviewRef(m_cUsedRecPicBufUnitList, rcList1, rcSliceHeader.getNumRefIdxActive(LIST_1), BACKWARD, rcSliceHeader);//JVT-W056 Samsung
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->isIdrNalUnit(), 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().getRequiredFrameNumUpdateBehaviourFlag() );
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 );
if( !pcSliceHeader->getInterViewRef()) //
{
RNOK( xUpdateMemory( pcSliceHeader ) );
}
RNOK( xOutput( rcOutputList, rcUnusedList ) );
}
RNOK( xDumpRecPicBuffer() );
m_pcCurrRecPicBufUnit = m_cFreeRecPicBufUnitList.popFront();
return Err::m_nOK;
}
// ----------------------------------------------------------------------
//
// FUNCTION: RemoveMultiviewRef
//
// INPUTS: pcRecPicBufUnit: A RecPicBufUnit representing a multiview
// reference to remove from the prediction
// buffer.
//
// PURPOSE: Remove a multiview prediction reference from the
// prediction list. We do this by manually removing
// the item from the m_cUsedRecPicBufUnitList instead
// of calling xSlidingWindow or xMMCO because we don't
// want to invoke other buffer management routines
// that could get confused by the multiview references.
//
// MODIFIED: Tue Mar 14, 2006
//
// ----------------------------------------------------------------------
void RecPicBuffer::RemoveMultiviewRef
(RecPicBufUnit* pcRecPicBufUnitToRemove) {
pcRecPicBufUnitToRemove->uninit();
m_cUsedRecPicBufUnitList.remove ( pcRecPicBufUnitToRemove );
m_cFreeRecPicBufUnitList.push_back( pcRecPicBufUnitToRemove );
}
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->getAdaptiveRefPicBufferingFlag() )
{
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 )
{
ROF( pcSliceHeader );
MmcoOp eMmcoOp;
const MmcoBuffer& rcMmcoBuffer = pcSliceHeader->getMmcoBuffer();
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();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -