gopdecoder.cpp
来自「JVT-S203 contains the JSVM 6 reference s」· C++ 代码 · 共 2,153 行 · 第 1/5 页
CPP
2,153 行
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 );
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( 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( 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( UInt mCurrFrameNum, UInt uiDiffOfPicNums )
{
// ROF( pcCurrentDPBUnit );
//UInt uiCurrPicNum = pcCurrentDPBUnit->getFrameNum();
Int iPicNumN = (Int)mCurrFrameNum - (Int)uiDiffOfPicNums - 1;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() && (*iter)->getFrameNum() == iPicNumN && (*iter)->isBaseRep() )
{
(*iter)->markNonRef();
}
}
return Err::m_nOK;
}
//JVT-S036 lsj end
ErrVal
DecodedPicBuffer::xMarkShortTermUnused( DPBUnit* pcCurrentDPBUnit, UInt uiDiffOfPicNums )
{
ROF( pcCurrentDPBUnit );
UInt uiCurrPicNum = pcCurrentDPBUnit->getFrameNum();
Int iPicNumN = (Int)uiCurrPicNum - (Int)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) == iPicNumN )
{
(*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())
{
RNOK( (*iter)->markNonRef() );
}
}
}
}
}
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 = 0;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
Bool bOutput = ( !(*iter)->isOutputted() && (*iter)->isExisting() && !(*iter)->isBaseRep() && !(*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 =====
DPBUnitList cOutputList;
Int iMaxPoc = iMinOutputPoc;
Int iMinPoc = MSYS_INT_MAX;
iter = m_cUsedDPBUnitList.begin();
for( ; iter != end; iter++ )
{
Bool bOutput = ( (*iter)->getPoc() <= iMinOutputPoc && !(*iter)->isOutputted() );
if( bOutput )
{
if( !(*iter)->isOutputted() )
{
RNOK( (*iter)->markOutputted() );
}
if( (*iter)->isExisting() && !(*iter)->isBaseRep() )
{
cOutputList.push_back( *iter );
if( (*iter)->getPoc() < iMinPoc )
{
iMinPoc = (*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 )
{
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 );
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 )
{
//===== 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++ )
{
Bool bOutput = ( !(*iter)->isOutputted() && (*iter)->isExisting() && !(*iter)->isBaseRep() );
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 )
{
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( iPoc > riMaxPoc )
{
riMaxPoc = iPoc;
}
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() );
m_cFreeDPBUnitList.push_back( pcDPBUnit );
}
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xStorePicture( DPBUnit* pcDPBUnit,
PicBufferList& rcOutputList,
PicBufferList& rcUnusedList,
Bool bTreatAsIdr )
{
ROF( pcDPBUnit == m_pcCurrDPBUnit ); // check
//---- fill border ----
RNOK( m_pcYuvBufferCtrl->initMb() );
RNOK( pcDPBUnit->getFrame()->extendFrame( NULL ) );
if( bTreatAsIdr )
{
//===== IDR pictures =====
/* // JVT-Q065 EIDR
Int iDummy;
RNOK( xClearOutputAll( rcOutputList, rcUnusedList, iDummy ) ); // clear and output all pictures
*/
m_cUsedDPBUnitList.push_back( pcDPBUnit ); // store current picture
}
else
{
//===== non-IDR picture =====
m_cUsedDPBUnitList.push_back( pcDPBUnit ); // store current picture
RNOK( xUpdateMemory( pcDPBUnit->getCtrlData().getSliceHeader() ) ); // memory update
RNOK( xOutput( rcOutputList, rcUnusedList ) ); // output
}
RNOK( xDumpDPB() );
m_pcCurrDPBUnit = m_cFreeDPBUnitList.popFront(); // new current DPB unit
m_pcCurrDPBUnit->getCtrlData().setSliceHeader( 0 );
m_pcCurrDPBUnit->getCtrlData().getMbDataCtrl()->reset();
m_pcCurrDPBUnit->getCtrlData().getMbDataCtrl()->clear();
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::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;
}
if( ! pcSliceHeader->getSPS().getRequiredFrameNumUpdateBehaviourFlag() )
{
printf("\nLOST PICTURES = %d\n", uiMissingFrames );
RERR();
}
else
{
for( UInt uiIndex = 1; uiIndex <= uiMissingFrames; uiIndex++ )
{
Bool bTreatAsIdr = ( m_cUsedDPBUnitList.empty() );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?