?? gopdecoder.cpp
字號:
m_pcCurrDPBUnit->destroy();
m_pcCurrDPBUnit = 0;
}
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++ )
{
Bool bNoOutput = ( !(*iter)->isExisting() || (*iter)->isBaseRep() || (*iter)->isOutputted() );
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();
//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 )
{
//===== 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 );
//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 =====
while( m_cUsedDPBUnitList.size() )
{
DPBUnit* pcDPBUnit = m_cUsedDPBUnitList.popFront();
RNOK( pcDPBUnit->uninit() );
m_cFreeDPBUnitList.push_back( pcDPBUnit );
}
return Err::m_nOK;
}
//JVT-T054{
ErrVal DecodedPicBuffer::xUpdateDPBUnitList(DPBUnit *pcDPBUnit)
{
ROF( pcDPBUnit == m_pcCurrDPBUnit ); // check
DPBUnit* pcElemToReplace = 0;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( !(*iter)->isBaseRep() && (*iter)->getPoc() == pcDPBUnit->getPoc()
&& (*iter)->getQualityLevel()+1 == pcDPBUnit->getQualityLevel() )
{
pcElemToReplace = (*iter);
m_cUsedDPBUnitList.remove(pcElemToReplace);
m_cFreeDPBUnitList.push_back(pcElemToReplace);
m_cUsedDPBUnitList.push_back(pcDPBUnit);
break;
}
}
return Err::m_nOK;
}
//JVT-T054}
ErrVal
DecodedPicBuffer::xStorePicture( DPBUnit* pcDPBUnit,
PicBufferList& rcOutputList,
PicBufferList& rcUnusedList,
Bool bTreatAsIdr,
UInt uiQualityLevel, //JVT-T054
Bool bRef) //JVT-T054
{
ROF( pcDPBUnit == m_pcCurrDPBUnit ); // check
//---- fill border ----
RNOK( m_pcYuvBufferCtrl->initMb() );
RNOK( pcDPBUnit->getFrame()->extendFrame( NULL ) );
//JVT-T054{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -