gopdecoder.cpp
来自「SVC最新更新代码」· C++ 代码 · 共 1,768 行 · 第 1/5 页
CPP
1,768 行
m_pcCurrDPBUnit->getCtrlData().setMbDataCtrl0L1( pcMbDataCtrl0 );
}
return Err::m_nOK;
}
CurrDPBUnit*
DecodedPicBuffer::getILPredDPBUnit()
{
ROTRS( m_pcCurrDPBUnitILPred->isCompleted(), m_pcCurrDPBUnitILPred );
ROTRS( m_pcCurrDPBUnit ->isCompleted(), m_pcCurrDPBUnit );
return 0;
}
Bool
DecodedPicBuffer::xIs2ndFieldOfCompFieldPair( const SliceHeader& rcSliceHeader )
{
ROFRS( m_pcLastDPBUnit, false );
ROFRS( m_pcLastDPBUnit->isExisting (), false );
ROFRS( rcSliceHeader.getFieldPicFlag (), false );
ROTRS( rcSliceHeader.getIdrFlag (), false );
ROTRS( rcSliceHeader.getDecRefPicMarking().hasMMCO5(), false );
ROFRS( rcSliceHeader.getPicType () + m_pcLastDPBUnit->getPicStatus () == FRAME, false );
ROFRS( rcSliceHeader.getFrameNum () == m_pcLastDPBUnit->getFrameNum (), false );
ROFRS( rcSliceHeader.isRefPic () == m_pcLastDPBUnit->isRefPicUnit (), false );
return true;
}
Bool
DecodedPicBuffer::xIs2ndFieldOfCompFieldPair( Bool bRefBasePic )
{
DPBUnit* pcLastDPBUnit = ( bRefBasePic ? m_pcLastDPBUnitRefBasePic : m_pcLastDPBUnit );
ROFRS( pcLastDPBUnit, false );
ROFRS( pcLastDPBUnit->isExisting (), false );
ROTRS( pcLastDPBUnit->getPicStatus() == FRAME, false );
ROFRS( pcLastDPBUnit->getPicStatus() + m_pcCurrDPBUnit->getPicStatus () == FRAME, false );
ROFRS( pcLastDPBUnit->getFrameNum () == m_pcCurrDPBUnit->getFrameNum (), false );
ROFRS( pcLastDPBUnit->isRefPicUnit() == m_pcCurrDPBUnit->isRefPicUnit (), false );
return true;
}
ErrVal
DecodedPicBuffer::xInsertNonExistingFrame( const SliceHeader* pcSliceHeader, UInt uiFrameNum )
{
//===== determine POC =====
Int iTopFieldPoc = ( pcSliceHeader ? pcSliceHeader->getPoc( TOP_FIELD ) : MSYS_INT_MIN );
Int iBotFieldPoc = ( pcSliceHeader ? pcSliceHeader->getPoc( BOT_FIELD ) : MSYS_INT_MIN );
//===== insert new non-existing frame unit =====
ROT( m_cFreeDPBUnitList.empty() );
DPBUnit* pcDPBUnit = m_cFreeDPBUnitList.popFront();
RNOK( pcDPBUnit->setNonExisting( uiFrameNum, iTopFieldPoc, iBotFieldPoc ) );
m_cUsedDPBUnitList.push_back( pcDPBUnit );
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xInsertCurrentInNewBuffer( DPBUnit*& rpcStoredDPBUnit, Bool bRefBasePic )
{
ROF ( m_uiMaxNumRefFrames > ( bRefBasePic ? 1U : 0U ) );
ROF ( m_pcCurrDPBUnit->isCompleted() );
ROT ( m_cFreeDPBUnitList.empty() );
ROF(( rpcStoredDPBUnit = m_cFreeDPBUnitList.popFront() ));
RNOK( m_pcCurrDPBUnit->store( *rpcStoredDPBUnit, bRefBasePic ) );
m_cUsedDPBUnitList.push_back( rpcStoredDPBUnit );
if( ! bRefBasePic && m_pcCurrDPBUnit->isRefPicUnit() )
{
m_uiLastRefFrameNum = m_pcCurrDPBUnit->getFrameNum();
}
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xCheckGapsInFrameNum( const SliceHeader& rcSliceHeader, PocCalculator& rcPocCalculator, PicBufferList& rcOutputList, PicBufferList& rcUnusedList )
{
ROTRS( xIs2ndFieldOfCompFieldPair ( rcSliceHeader ), Err::m_nOK );
ROTRS( rcSliceHeader.getIdrFlag (), Err::m_nOK );
ROTRS( rcSliceHeader.getFrameNum () == ( ( m_uiLastRefFrameNum + 1 ) % m_uiMaxFrameNum ), Err::m_nOK );
SliceHeader* pcNonExSliceHeader = 0;
UInt uiCurrFrameNum = rcSliceHeader.getFrameNum();
UInt uiMissingFrames = uiCurrFrameNum - m_uiLastRefFrameNum - 1 + ( uiCurrFrameNum <= m_uiLastRefFrameNum ? m_uiMaxFrameNum : 0 );
if( !rcSliceHeader.getSPS().getGapsInFrameNumValueAllowedFlag() )
{
fprintf( stderr, "\nLOST FRAMES = %d\n", uiMissingFrames );
RERR();
}
if( rcSliceHeader.getSPS().getPicOrderCntType() )
{
ROF(( pcNonExSliceHeader = new SliceHeader( rcSliceHeader ) ));
pcNonExSliceHeader->setNalRefIdc ( NAL_REF_IDC_PRIORITY_HIGH );
pcNonExSliceHeader->setNalUnitType ( NAL_UNIT_CODED_SLICE );
pcNonExSliceHeader->setIdrFlag ( false );
pcNonExSliceHeader->setFieldPicFlag ( false );
pcNonExSliceHeader->setBottomFieldFlag ( false );
pcNonExSliceHeader->setDeltaPicOrderCnt0 ( 0 );
pcNonExSliceHeader->setDeltaPicOrderCnt1 ( 0 );
}
while( uiMissingFrames-- )
{
UInt uiFrameNum = ( m_uiLastRefFrameNum + 1 ) % m_uiMaxFrameNum;
m_uiLastRefFrameNum = uiFrameNum;
if( pcNonExSliceHeader )
{
pcNonExSliceHeader ->setFrameNum ( uiFrameNum );
RNOK( rcPocCalculator.calculatePoc( *pcNonExSliceHeader ) );
}
RNOK( xSlidingWindow ( uiFrameNum ) );
RNOK( xInsertNonExistingFrame ( pcNonExSliceHeader, uiFrameNum ) );
RNOK( xBumpingOutput ( rcOutputList, rcUnusedList ) );
RNOK( xCheckBufferStatus () );
}
m_pcLastDPBUnit = 0;
m_pcLastDPBUnitRefBasePic = 0;
ROF( ( ( m_uiLastRefFrameNum + 1 ) % m_uiMaxFrameNum ) == uiCurrFrameNum );
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xUpdateAndStoreCurrentPic( PocCalculator& rcPocCalculator, PicBufferList& rcOutputList, PicBufferList& rcUnusedList )
{
ROF( m_bInitDone && m_bInitBufferDone );
ROF( m_pcCurrDPBUnit->isCompleted() );
SliceHeader* pcSliceHeader = m_pcCurrDPBUnit->getSliceHeader();
ROF( pcSliceHeader );
ROF( pcSliceHeader->isRefPic () == m_pcCurrDPBUnit->isRefPicUnit () );
ROF( pcSliceHeader->getOutputFlag () == m_pcCurrDPBUnit->isWaitingForOutput () );
ROF( pcSliceHeader->getFrameNum () == m_pcCurrDPBUnit->getFrameNum () );
UInt uiCurrFrameNum = pcSliceHeader->getFrameNum ();
Bool bIsIDR = pcSliceHeader->getIdrFlag ();
Bool bIsRefPic = pcSliceHeader->isRefPic ();
Bool bIsOutput = pcSliceHeader->getOutputFlag();
Bool bIs2ndFld = xIs2ndFieldOfCompFieldPair ();
Bool bIs2ndFldBase = xIs2ndFieldOfCompFieldPair ( true );
Bool bStoredAsLongTerm = false;
//===== possible output of single non-reference field that might occupy an extra DPB unit (for output of complementary field pairs) =====
if( ! bIs2ndFld )
{
RNOK ( xBumpingOutput ( rcOutputList, rcUnusedList ) );
RNOK ( xCheckBufferStatus() );
}
//===== non-reference/non-output picture =====
if( ! bIsRefPic && ! bIsOutput )
{
RNOK ( m_pcCurrDPBUnit->uninit () );
RNOK ( xCheckBufferStatus () );
RNOK ( xDumpDPB ( "after update (non-output and non-ref pic)" ) );
m_pcLastDPBUnit = 0;
m_pcLastDPBUnitRefBasePic = 0;
return Err::m_nOK;
}
//===== 2nd field of non-reference/output complementary field pair =====
if( ! bIsRefPic && bIs2ndFld )
{
ROT ( m_pcLastDPBUnitRefBasePic );
RNOK ( m_pcCurrDPBUnit->store ( *m_pcLastDPBUnit ) );
RNOK ( m_pcCurrDPBUnit->uninit () );
RNOK ( xBumpingOutput ( rcOutputList, rcUnusedList ) );
RNOK ( xCheckBufferStatus () );
RNOK ( xDumpDPB ( "after update (non-ref 2nd field)" ) );
return Err::m_nOK;
}
//===== non-reference/output frame/field (not 2nd field of a complementary field pair) =====
if( ! bIsRefPic )
{
RNOK ( xInsertCurrentInNewBuffer ( m_pcLastDPBUnit ) );
RNOK ( m_pcCurrDPBUnit->uninit () );
if( ! pcSliceHeader->getFieldPicFlag () )
{
RNOK( xBumpingOutput ( rcOutputList, rcUnusedList ) );
RNOK( xCheckBufferStatus () );
RNOK( xDumpDPB ( "after update (non-ref frame)" ) );
}
else
{
RNOK( xDumpDPB ( "after update (non-ref 1st field)" ) );
}
m_pcLastDPBUnitRefBasePic = 0;
return Err::m_nOK;
}
//===== IDR picture =====
if( bIsIDR )
{
ROF ( m_cUsedDPBUnitList.empty() ); // has been cleaned in initCurrDPBUnit()
ROT ( m_pcLastDPBUnit );
ROT ( m_pcLastDPBUnitRefBasePic );
if( pcSliceHeader->getLongTermReferenceFlag() )
{
m_iMaxLongTermFrameIdx = 0;
RNOK( m_pcCurrDPBUnit->markLongTerm ( pcSliceHeader->getPicType(), m_iMaxLongTermFrameIdx ) );
}
RNOK ( xInsertCurrentInNewBuffer ( m_pcLastDPBUnit ) );
if( pcSliceHeader->getStoreRefBasePicFlag() )
{
RNOK( xInsertCurrentInNewBuffer ( m_pcLastDPBUnitRefBasePic, true ) );
}
RNOK ( m_pcCurrDPBUnit->uninit () );
RNOK ( xCheckBufferStatus () );
RNOK ( xDumpDPB ( "after update (IDR pic)" ) );
return Err::m_nOK;
}
//===== non-IDR reference pictures =====
//----- MMCO for reference base pictures -----
if( pcSliceHeader->getDecRefBasePicMarking().getAdaptiveRefPicMarkingModeFlag() )
{
RNOK( xMMCO( rcPocCalculator, *pcSliceHeader, bStoredAsLongTerm, true ) );
ROT ( bStoredAsLongTerm );
}
//----- memory management for decoded picture -----
if( pcSliceHeader->getDecRefPicMarking().getAdaptiveRefPicMarkingModeFlag() )
{
RNOK( xMMCO( rcPocCalculator, *pcSliceHeader, bStoredAsLongTerm ) );
}
else if( ! bIs2ndFld )
{
RNOK( xSlidingWindow( uiCurrFrameNum ) );
}
//----- store pictures -----
if( ! bStoredAsLongTerm )
{
if( bIs2ndFld )
{
RNOK( m_pcCurrDPBUnit->store ( *m_pcLastDPBUnit ) );
}
else
{
RNOK( xInsertCurrentInNewBuffer ( m_pcLastDPBUnit ) );
}
if( pcSliceHeader->getStoreRefBasePicFlag() )
{
if( bIs2ndFldBase )
{
RNOK( m_pcCurrDPBUnit->store ( *m_pcLastDPBUnitRefBasePic, true ) );
}
else
{
RNOK( xSlidingWindow ( uiCurrFrameNum ) );
RNOK( xInsertCurrentInNewBuffer ( m_pcLastDPBUnitRefBasePic, true ) );
}
}
else
{
m_pcLastDPBUnitRefBasePic = 0;
}
}
//----- uninit, output, check ----
RNOK( m_pcCurrDPBUnit->uninit () );
RNOK( xBumpingOutput ( rcOutputList, rcUnusedList ) );
RNOK( xCheckBufferStatus () );
RNOK( xDumpDPB ( "after update (non-IDR ref pic)" ) );
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xCheckBufferStatus()
{
ROF( m_bInitDone && m_bInitBufferDone );
UInt uiNumNonRequired = 0;
UInt uiNumRequiredRef = 0;
UInt uiNumRequiredNonRef = 0;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
RNOK( (*iter)->checkStatus( m_iMaxLongTermFrameIdx ) );
if( ! (*iter)->isRequired () )
{
uiNumNonRequired++;
}
else if( (*iter)->isUsedForRef() )
{
uiNumRequiredRef++;
}
else
{
uiNumRequiredNonRef++;
}
}
ROT( uiNumNonRequired );
ROF( uiNumRequiredRef <= m_uiMaxNumRefFrames );
ROF( uiNumRequiredRef + uiNumRequiredNonRef <= m_uiDPBSizeInFrames );
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xBumpingOutput( PicBufferList& rcOutputList, PicBufferList& rcUnusedList, Bool bOutputAll )
{
ROF( m_bInitDone && m_bInitBufferDone );
//===== determine number of required and non-required picture and determine DPB unit with minimum POC =====
DPBUnitList cSortedByPocList;
DPBUnitList cNonRequiredList;
UInt uiNumRequiredRef = 0;
UInt uiNumRequiredNonRef = 0;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( ! (*iter)->isRequired() )
{
cNonRequiredList.push_back( *iter );
}
else
{
if( (*iter)->isUsedForRef() )
{
uiNumRequiredRef++;
}
else
{
uiNumRequiredNonRef++;
}
if( (*iter)->isWaitingForOutput() )
{
//----- insert in POC sorted list -----
DPBUnitList::iterator iterPocList = cSortedByPocList.begin();
DPBUnitList::iterator endPocList = cSortedByPocList.end ();
for( ; iterPocList != endPocList && (*iterPocList)->getPoc() < (*iter)->getPoc(); iterPocList++ );
cSortedByPocList.insert( iterPocList, *iter );
}
}
}
ROT( uiNumRequiredRef > m_uiDPBSizeInFrames );
ROT( uiNumRequiredRef && bOutputAll );
//===== output non-reference unit with minimum POC when required =====
while( uiNumRequiredRef + uiNumRequiredNonRef > m_uiDPBSizeInFrames || ( bOutputAll && uiNumRequiredNonRef ) )
{
DPBUnit* pcDPBUnitToOutput = cSortedByPocList.popFront();
ROF ( pcDPBUnitToOutput );
RNOK( pcDPBUnitToOutput->output( m_cPicBufferList, rcOutputList, rcUnusedList ) );
if( ! pcDPBUnitToOutput->isUsedForRef() )
{
cNonRequiredList.push_back( pcDPBUnitToOutput );
uiNumRequiredNonRef--;
}
}
//===== clean-up used DPB unit list =====
while( cNonRequiredList.size() )
{
DPBUnit* pcDPBUnit = cNonRequiredList.popFront();
ROF ( pcDPBUnit );
RNOK( pcDPBUnit->uninit() );
m_cUsedDPBUnitList.remove ( pcDPBUnit );
m_cFreeDPBUnitList.push_back( pcDPBUnit );
}
ROF( ! bOutputAll || m_cUsedDPBUnitList.empty() );
return Err::m_nOK;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?