📄 gopdecoder.cpp
字号:
ErrVal
DecodedPicBuffer::xClearBuffer()
{
//===== remove non-output/non-ref pictures =====
//--- store in temporary list ---
DPBUnitList cTempList;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
const Bool bNoOutput = ( ! (*iter)->isExisting() || (*iter)->isBaseRep() || (*iter)->isOutputted() );
const Bool bNonRef = ( ! (*iter)->isNeededForRef() );
if( bNonRef && bNoOutput )
{
cTempList.push_back( *iter );
}
}
//--- move to free list ---
while( cTempList.size() )
{
DPBUnit* pcDPBUnit = cTempList.popFront();
RNOK( pcDPBUnit->uninit() );
m_cUsedDPBUnitList.remove( pcDPBUnit );
AOT( pcDPBUnit == NULL)
m_cFreeDPBUnitList.push_back( pcDPBUnit );
}
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::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 =====
RNOK( xClearBuffer() );
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xMMCO( SliceHeader* pcSliceHeader )
{
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( pcSliceHeader->getPicType(), m_pcCurrDPBUnit, 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:
fprintf( stderr,"\nERROR: MMCO COMMAND currently not supported in the software\n\n" );
RERR();
}
}
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::MMCOBase( SliceHeader* pcSliceHeader, UInt mCurrFrameNum )
{
ROF( pcSliceHeader );
Mmco eMmcoOp;
const DecRefPicMarking& rcMmcoBaseBuffer = pcSliceHeader->getDecRefBasePicMarking();
Int iIndex = 0;
UInt uiVal1, uiVal2;
while( MMCO_END != (eMmcoOp = rcMmcoBaseBuffer.get( iIndex++ ).getCommand( uiVal1, uiVal2 ) ) )
{
switch( eMmcoOp )
{
case MMCO_SHORT_TERM_UNUSED:
RNOK( xMarkShortTermUnusedBase( pcSliceHeader->getPicType(), mCurrFrameNum, 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:
fprintf( stderr,"\nERROR: MMCO COMMAND currently not supported in the software\n\n" );
RERR();
}
}
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xMarkShortTermUnusedBase( const PicType eCurrentPicType, UInt mCurrFrameNum, UInt uiDiffOfPicNums )
{
UInt uiCurrPicNum = ( eCurrentPicType==FRAME ? mCurrFrameNum
: mCurrFrameNum*2+1 );
UInt uiPicNumN = uiCurrPicNum - uiDiffOfPicNums - 1;
PicType ePicType;
xSetIdentifier( uiPicNumN, ePicType, eCurrentPicType );
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() && (*iter)->getFrameNum() == (Int)uiPicNumN && (*iter)->isBaseRep() )
{
DPBUnit* pcDPBUnit = (*iter);
RNOK( pcDPBUnit->uninit() );
m_cUsedDPBUnitList.remove(pcDPBUnit);
m_cFreeDPBUnitList.push_back( pcDPBUnit );
return Err::m_nOK;
}
}
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xMarkShortTermUnused( const PicType eCurrentPicType, const DPBUnit* pcCurrentDPBUnit, UInt uiDiffOfPicNums )
{
ROF( pcCurrentDPBUnit );
UInt uiCurrPicNum = ( eCurrentPicType==FRAME ? pcCurrentDPBUnit->getFrameNum()
: pcCurrentDPBUnit->getFrameNum()*2+1 );
UInt uiPicNumN = uiCurrPicNum - uiDiffOfPicNums - 1;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() && (*iter)->getPicNum(uiCurrPicNum,m_uiMaxFrameNum) == (Int)uiPicNumN )
{
(*iter)->markNonRef();
}
}
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xSlidingWindow()
{
//===== get number of reference frames =====
UInt uiCurrNumRefFrames = 0;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() && !(*iter)->isBaseRep() )
{
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_cUsedDPBUnitList.begin();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() && !(*iter)->isBaseRep() )
{
uiRefFramesToRemove--;
if( uiRefFramesToRemove == 0 )
{
break;
}
}
}
ROT( uiRefFramesToRemove );
//--- delete reference label ---
end = ++iter;
iter = m_cUsedDPBUnitList.begin();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() )
{
RNOK( (*iter)->markNonRef() );
}
}
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::slidingWindowBase( UInt mCurrFrameNum )
{
//===== get number of reference frames =====
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
DPBUnitList::iterator iiter;
for( ; iter != end; iter++ )
{
if( (*iter)->isBaseRep() && (*iter)->getFrameNum() != mCurrFrameNum )
{
for( iiter = m_cUsedDPBUnitList.begin(); iiter != end; iiter++ )
{
if ( (*iiter)->getFrameNum() == (*iter)->getFrameNum() && !(*iiter)->isBaseRep() )
{
if((*iter)->isNeededForRef())
{
DPBUnit* pcDPBUnit = (*iter);
RNOK( pcDPBUnit->uninit() );
m_cUsedDPBUnitList.remove(pcDPBUnit);
m_cFreeDPBUnitList.push_back( pcDPBUnit );
return Err::m_nOK;
}
}
}
}
}
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xOutput( PicBufferList& rcOutputList,
PicBufferList& rcUnusedList )
{
ROTRS( m_cFreeDPBUnitList.size(), Err::m_nOK ); // no need for output
//===== smallest non-ref/output poc value =====
Int iMinOutputPoc = MSYS_INT_MAX;
DPBUnit* pcElemToRemove = NULL;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
const Bool bOutput = ( !(*iter)->isOutputted() && (*iter)->isExisting() && !(*iter)->isBaseRep() && !(*iter)->isNeededForRef() );
if( bOutput && (*iter)->getFrame()->getPoc() < iMinOutputPoc )
{
iMinOutputPoc = (*iter)->getFrame()->getPoc();
pcElemToRemove = (*iter);
}
}
ROF( pcElemToRemove ); // error, nothing can be removed
//===== copy all output elements to temporary list =====
DPBUnitList cOutputList;
Int iMaxPoc = iMinOutputPoc;
Int iMinPoc = MSYS_INT_MAX;
iter = m_cUsedDPBUnitList.begin();
for( ; iter != end; iter++ )
{
const Bool bOutput = ( (*iter)->getFrame()->getPoc() <= iMinOutputPoc && !(*iter)->isOutputted() );
if( bOutput )
{
if( !(*iter)->isOutputted() )
{
RNOK( (*iter)->markOutputted() );
}
if( (*iter)->isExisting() && !(*iter)->isBaseRep() )
{
cOutputList.push_back( *iter );
if( (*iter)->getFrame()->getPoc() < iMinPoc )
{
iMinPoc = (*iter)->getFrame()->getPoc();
}
}
}
}
//===== real output =====
for( Int iPoc = iMinPoc; iPoc <= iMaxPoc; iPoc++ )
{
iter = cOutputList.begin();
end = cOutputList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->getFrame()->getPoc() == iPoc )
{
DPBUnit* pcDPBUnit = *iter;
cOutputList.remove( pcDPBUnit );
//----- output -----
ROT( m_cPicBufferList.empty() );
PicBuffer* pcPicBuffer = m_cPicBufferList.popFront();
if( pcPicBuffer->isUsed() )
{
pcPicBuffer->setUnused();
}
pcDPBUnit->getFrame()->store( pcPicBuffer );
rcOutputList.push_back( pcPicBuffer );
rcUnusedList.push_back( pcPicBuffer );
break; // only one picture per Poc
}
}
}
ROT( cOutputList.size() );
//===== clear buffer =====
RNOK( xClearBuffer() );
//===== check =====
ROT( m_cFreeDPBUnitList.empty() ); // this should never happen
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xClearOutputAll( PicBufferList& rcOutputList,
PicBufferList& rcUnusedList,
Bool bFinal )
{
//===== create output list =====
DPBUnitList cOutputList;
Int iMinPoc = MSYS_INT_MAX;
Int iMaxPoc = MSYS_INT_MIN;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
const Bool bOutput = ( !(*iter)->isOutputted() && (*iter)->isExisting() && !(*iter)->isBaseRep() );
if( bOutput )
{
cOutputList.push_back( *iter );
if( (*iter)->getFrame()->getPoc() < iMinPoc ) iMinPoc = (*iter)->getFrame()->getPoc();
if( (*iter)->getFrame()->getPoc() > iMaxPoc ) iMaxPoc = (*iter)->getFrame()->getPoc();
}
}
//===== real output =====
for( Int iPoc = iMinPoc; iPoc <= iMaxPoc; iPoc++ )
{
iter = cOutputList.begin();
end = cOutputList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->getFrame()->getPoc() == iPoc )
{
DPBUnit* pcDPBUnit = *iter;
cOutputList.remove( pcDPBUnit );
//----- output -----
ROT( m_cPicBufferList.empty() );
PicBuffer* pcPicBuffer = m_cPicBufferList.popFront();
pcDPBUnit->getFrame()->store( pcPicBuffer );
rcOutputList.push_back( pcPicBuffer );
rcUnusedList.push_back( pcPicBuffer );
if(pcPicBuffer->isUsed())
{
pcPicBuffer->setUnused();
}
pcDPBUnit->getCtrlData().setSliceHeader(NULL);
break; // only one picture per Poc
}
}
}
ROT( cOutputList.size() );
//===== uninit all elements and move to free list =====
while( m_cUsedDPBUnitList.size() )
{
DPBUnit* pcDPBUnit = m_cUsedDPBUnitList.popFront();
RNOK( pcDPBUnit->uninit() );
AOT( pcDPBUnit == NULL)
m_cFreeDPBUnitList.push_back( pcDPBUnit );
}
ROTRS( ! bFinal , Err::m_nOK );
// release remaining buffers
while( m_cPicBufferList.size() )
{
rcUnusedList.push_back( m_cPicBufferList.popFront() );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -