📄 gopdecoder.cpp
字号:
m_cFreeDPBUnitList += m_cUsedDPBUnitList;
m_cUsedDPBUnitList.clear();
while( m_cFreeDPBUnitList.size() )
{
DPBUnit* pcDPBUnit = m_cFreeDPBUnitList.popFront();
if( pcDPBUnit )
{
RNOK( pcDPBUnit->destroy() );
pcDPBUnit = NULL;
}
}
if( m_pcCurrDPBUnit )
{
RNOK( m_pcCurrDPBUnit->destroy() );
m_pcCurrDPBUnit = NULL;
}
return Err::m_nOK;
}
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->getAdaptiveRefPicBufferingFlag() )
{
RNOK( xMMCO( pcSliceHeader ) );
}
else
{
RNOK( xSlidingWindow() );
}
//===== clear buffer =====
RNOK( xClearBuffer() );
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::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( 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;
}
//JVT-S036 lsj start
ErrVal
DecodedPicBuffer::xMMCOBase( SliceHeader* pcSliceHeader, UInt mCurrFrameNum )
{
ROF( pcSliceHeader );
MmcoOp eMmcoOp;
const MmcoBuffer& rcMmcoBaseBuffer = pcSliceHeader->getMmcoBaseBuffer();
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 )
{
// ROF( pcCurrentDPBUnit );
//UInt uiCurrPicNum = pcCurrentDPBUnit->getFrameNum();
// TMM_INTERLACE
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() )
{
//bug-fix base_rep 0925{{
DPBUnit* pcDPBUnit = (*iter);
RNOK( pcDPBUnit->uninit() );
m_cUsedDPBUnitList.remove(pcDPBUnit);
m_cFreeDPBUnitList.push_back( pcDPBUnit );
return Err::m_nOK;
//bug-fix base_rep 0925}}
}
}
return Err::m_nOK;
}
//JVT-S036 lsj end
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;
}
//JVT-S036 lsj start
ErrVal
DecodedPicBuffer::xSlidingWindowBase( 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())
{
//bug-fix base_rep 0925{{
DPBUnit* pcDPBUnit = (*iter);
RNOK( pcDPBUnit->uninit() );
m_cUsedDPBUnitList.remove(pcDPBUnit);
m_cFreeDPBUnitList.push_back( pcDPBUnit );
return Err::m_nOK;
//bug-fix base_rep 0925}}
}
}
}
}
}
return Err::m_nOK;
}
//JVT-S036 lsj end
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();
//JVT-T054{
if(pcPicBuffer->isUsed())
pcPicBuffer->setUnused();
//JVT-T054}
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,
Int& riMaxPoc,
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 );
//JVT-T054{
if(pcPicBuffer->isUsed())
pcPicBuffer->setUnused();
pcDPBUnit->getCtrlData().setSliceHeader(NULL);
//JVT-T054}
if( iPoc > riMaxPoc )
{
riMaxPoc = iPoc;
}
break; // only one picture per Poc
}
}
}
ROT( cOutputList.size() );
//===== uninit all elements and move to free list =====
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -