gopdecoder.cpp
来自「SVC最新更新代码」· C++ 代码 · 共 1,768 行 · 第 1/5 页
CPP
1,768 行
ErrVal
DecodedPicBuffer::xMarkAllUnusedForRef( Bool bRemoveOutputFlag )
{
m_iMaxLongTermFrameIdx = -1;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
RNOK( (*iter)->markUnusedForRef( FRAME, bRemoveOutputFlag ) );
}
m_pcLastDPBUnit = 0;
m_pcLastDPBUnitRefBasePic = 0;
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xSlidingWindow( UInt uiCurrFrameNum )
{
ROF( m_bInitDone && m_bInitBufferDone );
//===== determine number of reference frames and DPB units with smallest FrameNumWrap value =====
UInt uiNumShortTerm = 0;
UInt uiNumLongTerm = 0;
Int iMinFrameNumWrap = MSYS_INT_MAX;
DPBUnit* pcMinFrameNumUnit = 0;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isLongTermUnit() )
{
uiNumLongTerm++;
}
else if( (*iter)->isShortTermUnit() )
{
uiNumShortTerm++;
if( ( (*iter)->getFrameNumWrap( uiCurrFrameNum, m_uiMaxFrameNum ) < iMinFrameNumWrap ) ||
( (*iter)->getFrameNumWrap( uiCurrFrameNum, m_uiMaxFrameNum ) == iMinFrameNumWrap && (*iter)->isRefBasePicUnit() ) )
{
pcMinFrameNumUnit = *iter;
iMinFrameNumWrap = pcMinFrameNumUnit->getFrameNumWrap( uiCurrFrameNum, m_uiMaxFrameNum );
}
}
}
//===== check number of reference frames =====
ROTRS ( uiNumShortTerm + uiNumLongTerm < m_uiMaxNumRefFrames, Err::m_nOK );
ROT ( uiNumShortTerm + uiNumLongTerm > m_uiMaxNumRefFrames );
ROF ( pcMinFrameNumUnit ); // no short-term reference picture available
//===== mark DPB unit with smallest FrameNumWrap value as "unused for reference" =====
RNOK ( pcMinFrameNumUnit->markUnusedForRef( FRAME ) );
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xMMCO( PocCalculator& rcPocCalculator, SliceHeader& rcSliceHeader, Bool& rbMMCO6, Bool bRefBasePic )
{
Mmco eMmcoOp;
UInt uiVal1, uiVal2;
UInt uiCurrFrameNum = rcSliceHeader.getFrameNum ();
PicType eCurrPicType = rcSliceHeader.getPicType ();
const DecRefPicMarking& rcMmcoBuffer = ( bRefBasePic ? rcSliceHeader.getDecRefBasePicMarking() : rcSliceHeader.getDecRefPicMarking() );
Int iIndex = 0;
Int iMMCO6LTFrmIdx = -1;
Bool bMMCO123 = false;
Bool bMMCO4 = false;
Bool bMMCO5 = false;
rbMMCO6 = false;
while( MMCO_END != ( eMmcoOp = rcMmcoBuffer.get( iIndex++ ).getCommand( uiVal1, uiVal2 ) ) )
{
switch( eMmcoOp )
{
case MMCO_SHORT_TERM_UNUSED:
ROT ( bMMCO5 );
RNOK( xMarkShortTermUnused( uiCurrFrameNum, eCurrPicType, uiVal1, bRefBasePic ) );
bMMCO123 = true;
break;
case MMCO_LONG_TERM_UNUSED:
ROT ( bMMCO5 );
ROT ( rbMMCO6 && iMMCO6LTFrmIdx == (Int)( eCurrPicType == FRAME ? uiVal1 : ( uiVal1 >> 1 ) ) );
RNOK( xMarkLongTermUnused( eCurrPicType, uiVal1, bRefBasePic ) );
bMMCO123 = true;
break;
case MMCO_ASSIGN_LONG_TERM:
ROT ( bRefBasePic );
ROT ( bMMCO5 );
ROT ( rbMMCO6 && iMMCO6LTFrmIdx == (Int)uiVal2 );
ROF ( (Int)uiVal2 <= m_iMaxLongTermFrameIdx );
RNOK( xAssignLongTermIndex( uiCurrFrameNum, eCurrPicType, uiVal1, uiVal2 ) );
bMMCO123 = true;
break;
case MMCO_MAX_LONG_TERM_IDX:
ROT ( bRefBasePic );
ROT ( bMMCO4 );
ROT ( rbMMCO6 && iMMCO6LTFrmIdx >= (Int)uiVal1 )
RNOK( xSetMaxLongTermIndex( uiVal1 ) );
bMMCO4 = true;
break;
case MMCO_RESET:
ROT ( bRefBasePic );
ROT ( bMMCO123 );
ROT ( bMMCO5 );
ROT ( rbMMCO6 );
RNOK( xReset( rcPocCalculator, rcSliceHeader ) );
bMMCO5 = true;
break;
case MMCO_SET_LONG_TERM:
ROT ( bRefBasePic );
ROT ( rbMMCO6 );
ROF ( (Int)uiVal1 <= m_iMaxLongTermFrameIdx );
RNOK( xStoreCurrentLongTerm( uiVal1, rcSliceHeader.getStoreRefBasePicFlag() ) );
rbMMCO6 = true;
iMMCO6LTFrmIdx = uiVal1;
break;
default:
ROT ( true );
}
}
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xMarkShortTermUnused( UInt uiCurrFrameNum, PicType eCurrPicType, UInt uiPicNumDiff, Bool bRefBasePic )
{
Int iCurrPicNum = ( eCurrPicType == FRAME ? (Int)uiCurrFrameNum : 2 * (Int)uiCurrFrameNum + 1 );
Int iPicNumX = ( iCurrPicNum - (Int)uiPicNumDiff - 1 );
PicType ePicTypeX = ( eCurrPicType == FRAME ? FRAME : ( iPicNumX % 2 ? eCurrPicType : PicType( FRAME - eCurrPicType ) ) );
UInt iFrameNumWrapX = ( eCurrPicType == FRAME ? iPicNumX : ( iPicNumX >> 1 ) );
//===== find short-term picture and mark "unused for reference" =====
DPBUnit* pcDPBUnit = 0;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isShortTermRef ( ePicTypeX ) &&
(*iter)->isRefBasePicUnit () == bRefBasePic &&
(*iter)->getFrameNumWrap ( uiCurrFrameNum, m_uiMaxFrameNum ) == iFrameNumWrapX )
{
ROT( pcDPBUnit );
pcDPBUnit = *iter;
}
}
ROF ( pcDPBUnit ); // not found
RNOK( pcDPBUnit->markUnusedForRef( ePicTypeX ) );
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xMarkLongTermUnused( PicType eCurrPicType, UInt uiLongTermPicNum, Bool bRefBasePic )
{
PicType ePicTypeX = ( eCurrPicType == FRAME ? FRAME : ( (Int)uiLongTermPicNum % 2 ? eCurrPicType : PicType( FRAME - eCurrPicType ) ) );
Int iLongTermFrameIdx = ( eCurrPicType == FRAME ? (Int)uiLongTermPicNum : ( (Int)uiLongTermPicNum >> 1 ) );
//===== find long-term picture and mark "unused for reference" =====
DPBUnit* pcDPBUnit = 0;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isLongTermRef ( ePicTypeX ) &&
(*iter)->isRefBasePicUnit () == bRefBasePic &&
(*iter)->getLongTermIndex () == iLongTermFrameIdx )
{
ROT( pcDPBUnit );
pcDPBUnit = *iter;
}
}
ROF ( pcDPBUnit ); // not found
RNOK( pcDPBUnit->markUnusedForRef( ePicTypeX ) );
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xAssignLongTermIndex( UInt uiCurrFrameNum, PicType eCurrPicType, UInt uiPicNumDiff, UInt uiLongTermFrameIndex )
{
ROF( (Int)uiLongTermFrameIndex <= m_iMaxLongTermFrameIdx );
Int iCurrPicNum = ( eCurrPicType == FRAME ? (Int)uiCurrFrameNum : 2 * (Int)uiCurrFrameNum + 1 );
Int iPicNumX = ( iCurrPicNum - (Int)uiPicNumDiff - 1 );
PicType ePicTypeX = ( eCurrPicType == FRAME ? FRAME : ( iPicNumX % 2 ? eCurrPicType : PicType( FRAME - eCurrPicType ) ) );
UInt iFrameNumWrapX = ( eCurrPicType == FRAME ? iPicNumX : ( iPicNumX >> 1 ) );
Int iLongTermFrameIdx = (Int)uiLongTermFrameIndex;
//===== mark long-term pictures with specified index as "unused for reference" =====
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isLongTermUnit () &&
(*iter)->getLongTermIndex () == iLongTermFrameIdx )
{
RNOK( (*iter)->markUnusedForRef( FRAME ) );
}
}
//===== find short-term pictures =====
DPBUnit* pcDPBUnit = 0;
DPBUnit* pcDPBUnitBase = 0;
iter = m_cUsedDPBUnitList.begin();
end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isShortTermRef ( ePicTypeX ) &&
(*iter)->getFrameNumWrap ( uiCurrFrameNum, m_uiMaxFrameNum ) == iFrameNumWrapX )
{
if( (*iter)->isRefBasePicUnit() )
{
ROT( pcDPBUnitBase );
pcDPBUnitBase = *iter;
}
else
{
ROT( pcDPBUnit );
pcDPBUnit = *iter;
}
}
}
//===== mark pictures =====
ROF ( pcDPBUnit );
RNOK ( pcDPBUnit ->markLongTerm( ePicTypeX, iLongTermFrameIdx ) );
ROFRS ( pcDPBUnitBase, Err::m_nOK );
RNOK ( pcDPBUnitBase ->markLongTerm( ePicTypeX, iLongTermFrameIdx ) );
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xSetMaxLongTermIndex( UInt uiMaxLongTermFrameIdxPlus1 )
{
m_iMaxLongTermFrameIdx = (Int)uiMaxLongTermFrameIdxPlus1 - 1;
//===== mark long-term pictures with higher index as "unused for reference" =====
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isLongTermUnit () &&
(*iter)->getLongTermIndex () > m_iMaxLongTermFrameIdx )
{
RNOK( (*iter)->markUnusedForRef( FRAME ) );
}
}
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xReset( PocCalculator& rcPocCalculator, SliceHeader& rcSliceHeader )
{
//===== check maximum POC of all required pictures =====
Int iMaxPoc = MSYS_INT_MIN;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isRequired() )
{
Int iPoc = (*iter)->getMaxPoc( rcSliceHeader.getSPS().getPicOrderCntType() == 0 );
iMaxPoc = max( iMaxPoc, iPoc );
}
}
ROF( m_pcCurrDPBUnit->getPoc() > iMaxPoc );
//===== mark all pictures as "unused for reference" =====
RNOK( xMarkAllUnusedForRef() );
//===== reset PocCalculator and POC values in slice Header =====
RNOK( rcPocCalculator .resetMMCO5 ( rcSliceHeader ) );
//===== update parameters in current DPB unit =====
ROF ( m_pcCurrDPBUnit->isCompleted() );
RNOK( m_pcCurrDPBUnit->resetMMCO5 ( rcSliceHeader ) );
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xStoreCurrentLongTerm( UInt uiLongTermFrameIndex, Bool bStoreRefBasePic )
{
Int iLongTermFrameIdx = (Int)uiLongTermFrameIndex;
ROF( iLongTermFrameIdx <= m_iMaxLongTermFrameIdx );
//===== mark long-term pictures with specified index as "unused for reference" =====
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isLongTermUnit () &&
(*iter)->getLongTermIndex () == iLongTermFrameIdx )
{
if( xIs2ndFieldOfCompFieldPair( bStoreRefBasePic ) )
{
ROF( *iter == ( bStoreRefBasePic ? m_pcLastDPBUnitRefBasePic : m_pcLastDPBUnit ) );
}
else
{
RNOK( (*iter)->markUnusedForRef( FRAME ) );
}
}
}
//===== mark current picture as long-term =====
RNOK( m_pcCurrDPBUnit->markLongTerm( m_pcCurrDPBUnit->getPicStatus(), uiLongTermFrameIndex ) );
//===== store current picture =====
if( xIs2ndFieldOfCompFieldPair() )
{
RNOK( m_pcCurrDPBUnit->store ( *m_pcLastDPBUnit ) );
}
else
{
RNOK( xInsertCurrentInNewBuffer ( m_pcLastDPBUnit ) );
}
//===== store reference base picture =====
if( bStoreRefBasePic )
{
if( xIs2ndFieldOfCompFieldPair( true ) )
{
RNOK( m_pcCurrDPBUnit->store ( *m_pcLastDPBUnitRefBasePic, true ) );
}
else
{
RNOK( xInsertCurrentInNewBuffer ( m_pcLastDPBUnitRefBasePic, true ) );
}
}
else
{
m_pcLastDPBUnitRefBasePic = 0;
}
return Err::m_nOK;
}
Bool
DecodedPicBuffer::xExistsRefBasePicShortTerm( UInt uiFrameNum )
{
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
ROTRS( (*iter)->isShortTermUnit() && (*iter)->isRefBasePicUnit() && (*iter)->getFrameNum() == uiFrameNum, true );
}
return false;
}
Bool
DecodedPicBuffer::xExistsRefBasePicLongTerm ( Int iLongTermFrameIdx )
{
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
ROTRS( (*iter)->isLongTermUnit() && (*iter)->isRefBasePicUnit() && (*iter)->getLongTermIndex() == iLongTermFrameIdx, true );
}
return false;
}
Bool
DecodedPicBuffer::xIsAvailableForRefLists( const DPBUnit* pcDPBUnit, Bool bFieldPicture, Bool bExcludeNonExisting, Bool bUseRefBasePic )
{
AOF ( pcDPBUnit );
ROFRS( bFieldPicture || pcDPBUnit->isRefFrame(), false );
ROTRS( bExcludeNonExisting && !pcDPBUnit->isExisting(), false );
if( !bUseRefBasePic )
{
ROTRS( pcDPBUnit->isUsedForRef () && ! pcDPBUnit->isRefBasePicUnit(), true );
return false;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?