📄 gopdecoder.cpp
字号:
}
return Err::m_nOK;
}
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)->getFrame()->getPoc() == pcDPBUnit->getFrame()->getPoc() && (*iter)->getQualityId()+1 == pcDPBUnit->getQualityId() )
{
pcElemToReplace = (*iter);
m_cUsedDPBUnitList.remove(pcElemToReplace);
m_cFreeDPBUnitList.push_back(pcElemToReplace);
m_cUsedDPBUnitList.push_back(pcDPBUnit);
RNOK( pcDPBUnit->switchMbDataCtrlBL( pcElemToReplace ) );
break;
}
}
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xStorePicture( DPBUnit* pcDPBUnit,
PicBufferList& rcOutputList,
PicBufferList& rcUnusedList,
Bool bTreatAsIdr,
Bool bFrameMbsOnlyFlag,
Bool bRef )
{
ROF( pcDPBUnit == m_pcCurrDPBUnit );
if( pcDPBUnit->isExisting() && pcDPBUnit->getCtrlData().getSliceHeader()->isH264AVCCompatible() )
{
MbDataCtrl* pcMbDataCtrl = pcDPBUnit->getCtrlData().getMbDataCtrl();
ROF( pcMbDataCtrl );
RNOK( pcDPBUnit->storeMbDataCtrlBL( pcMbDataCtrl ) );
}
//---- fill border ----
RNOK( m_pcYuvBufferCtrl->initMb() );
RNOK( pcDPBUnit->getFrame()->extendFrame( NULL, pcDPBUnit->getFrame()->getPicType(), bFrameMbsOnlyFlag ) );
if( !bRef )
{
if( bTreatAsIdr )
{
//===== IDR pictures =====
RNOK( xClearOutputAll( rcOutputList, rcUnusedList, false ) ); // 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
}
else
{
//replace previous version of current frame in usedDPBUnit by the new version
RNOK( xUpdateDPBUnitList(pcDPBUnit));
RNOK( xUpdateMemory( pcDPBUnit->getCtrlData().getSliceHeader() ) ); // memory update
RNOK( xOutput( rcOutputList, rcUnusedList ) ); // output
m_pcCurrDPBUnit = m_cFreeDPBUnitList.popBack();
}
m_pcCurrDPBUnit->getCtrlData().setSliceHeader( 0 );
m_pcCurrDPBUnit->getCtrlData().getMbDataCtrl()->reset();
m_pcCurrDPBUnit->getCtrlData().getMbDataCtrl()->clear();
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xCheckMissingPics( const SliceHeader* pcSliceHeader,
PicBufferList& rcOutputList,
PicBufferList& rcUnusedList )
{
ROTRS( pcSliceHeader->getIdrFlag(), 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().getGapsInFrameNumValueAllowedFlag() )
{
printf("\nLOST PICTURES = %d\n", uiMissingFrames );
RERR();
}
else
{
for( UInt uiIndex = 1; uiIndex <= uiMissingFrames; uiIndex++ )
{
const Bool bTreatAsIdr = ( m_cUsedDPBUnitList.empty() );
const Int iPoc = ( bTreatAsIdr ? 0 : m_cUsedDPBUnitList.back()->getFrame()->getPoc() );
const UInt uiFrameNum = ( m_uiLastRefFrameNum + uiIndex ) % m_uiMaxFrameNum;
RNOK( m_pcCurrDPBUnit->initNonEx( iPoc, uiFrameNum ) );
RNOK( xStorePicture( m_pcCurrDPBUnit, rcOutputList, rcUnusedList, bTreatAsIdr, pcSliceHeader->getSPS().getFrameMbsOnlyFlag(), false ) );
}
}
m_uiLastRefFrameNum = ( m_uiLastRefFrameNum + uiMissingFrames ) % m_uiMaxFrameNum;
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xDumpDPB()
{
#if 1 // NO_DEBUG
return Err::m_nOK;
#endif
printf("\nDECODED PICTURE BUFFER (Layer %d)\n", m_uiLayer );
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( Int iIndex = 0; iter != end; iter++, iIndex++ )
{
printf("\tPOS=%d:\tFN=%d\tPoc=%d\t%s\t", iIndex, (*iter)->getFrameNum(), (*iter)->getFrame()->getPoc(), ((*iter)->isNeededForRef()?"REF":" ") );
if( (*iter)->isOutputted() ) printf("Outputted ");
if( !(*iter)->isExisting () ) printf("NotExisting ");
if( (*iter)->isBaseRep () ) printf("BasRep ");
printf("\n");
}
printf("\n");
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xInitPrdListPSlice( RefFrameList& rcList0,
Frame* pcCurrentFrame,
PicType ePicType,
SliceType eSliceType )
{
rcList0.reset();
const Bool bBaseRep = m_pcCurrDPBUnit->useBasePred();
const UInt uiCurrFrameNum = m_pcCurrDPBUnit->getFrameNum();
//----- generate decreasing frame num wrap list -----
Bool bPicTypeModified = false;
if ( ePicType != FRAME && m_pcCurrDPBUnit->getPicType() == FRAME && m_pcCurrDPBUnit->isNeededForRef() )
{
m_pcCurrDPBUnit->setPicType( PicType( FRAME ^ ePicType ) );
bPicTypeModified = true;
rcList0.add( m_pcCurrDPBUnit->getFrame() ); // insert unit of first field
}
for( Int iMaxPicNum = (Int)uiCurrFrameNum; true; )
{
DPBUnit* pNext = NULL;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() &&
(*iter)->getPicNum(uiCurrFrameNum,m_uiMaxFrameNum) < iMaxPicNum &&
( !pNext || (*iter)->getPicNum(uiCurrFrameNum,m_uiMaxFrameNum) > pNext->getPicNum(uiCurrFrameNum,m_uiMaxFrameNum)
||((*iter)->getPicNum(uiCurrFrameNum,m_uiMaxFrameNum) == pNext->getPicNum(uiCurrFrameNum,m_uiMaxFrameNum) &&
(*iter)->isBaseRep() == bBaseRep) ) )
{
pNext = (*iter);
}
}
if( !pNext )
{
break;
}
iMaxPicNum = pNext->getPicNum(uiCurrFrameNum,m_uiMaxFrameNum);
RNOK( rcList0.add( pNext->getFrame() ) );
}
if( ePicType!=FRAME )
{
RNOK( xSetInitialRefFieldList( rcList0, pcCurrentFrame, ePicType, eSliceType ) ) ;
}
if( bPicTypeModified )
{
m_pcCurrDPBUnit->setPicType( FRAME );
}
return Err::m_nOK;
}
Void
DecodedPicBuffer::xSetIdentifier( UInt& uiNum, PicType& rePicType, const PicType eCurrentPicType )
{
if( eCurrentPicType==FRAME )
{
rePicType = FRAME;
}
else
{
if( uiNum % 2 )
{
rePicType = eCurrentPicType;
}
else if( eCurrentPicType==TOP_FIELD )
{
rePicType = BOT_FIELD;
}
else
{
rePicType = TOP_FIELD;
}
uiNum /= 2;
}
}
ErrVal
DecodedPicBuffer::xSetInitialRefFieldList( RefFrameList& rcList, Frame* pcCurrentFrame, PicType eCurrentPicType, SliceType eSliceType )
{
RefFrameList cTempList = rcList;
rcList.reset();
const PicType eOppositePicType = ( eCurrentPicType==TOP_FIELD ? BOT_FIELD : TOP_FIELD );
//----- initialize field list for short term pictures -----
UInt uiCurrentParityIndex = 0;
UInt uiOppositeParityIndex = 0;
while( uiCurrentParityIndex < cTempList.getSize() || uiOppositeParityIndex < cTempList.getSize() )
{
//--- current parity ---
while( uiCurrentParityIndex < cTempList.getSize() )
{
Frame* pcFrame = cTempList.getEntry( uiCurrentParityIndex++ );
if( pcFrame->getDPBUnit()->getPicType() & eCurrentPicType )
{
RNOK( rcList.add( pcFrame->getPic( eCurrentPicType ) ) );
break;
}
}
//--- opposite parity ---
while( uiOppositeParityIndex < cTempList.getSize() )
{
Frame* pcFrame = cTempList.getEntry( uiOppositeParityIndex++ );
if( pcFrame->getDPBUnit()->getPicType() & eOppositePicType )
{
RNOK( rcList.add( pcFrame->getPic( eOppositePicType ) ) );
break;
}
}
}
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xInitPrdListsBSlice( RefFrameList& rcList0,
RefFrameList& rcList1,
Frame* pcCurrentFrame,
PicType eCurrentPicType,
SliceType eSliceType )
{
rcList0.reset();
rcList1.reset();
RefFrameList cDecreasingPocList;
RefFrameList cIncreasingPocList;
const Bool bBaseRep = m_pcCurrDPBUnit->useBasePred();
const Int iCurrPoc = m_pcCurrDPBUnit->getFrame()->getPic( eCurrentPicType )->getPoc();
Int iCurrFramePoc = 0;
Bool bCurrUnitAdded = false;
if( eCurrentPicType != FRAME && m_pcCurrDPBUnit->getPicType() == FRAME && m_pcCurrDPBUnit->isNeededForRef() )
{
//----- temporarily add current DPB to DPB unit list -----
iCurrFramePoc = m_pcCurrDPBUnit->getFrame()->getPoc();
if( eCurrentPicType == TOP_FIELD ) m_pcCurrDPBUnit->getFrame()->setPoc( m_pcCurrDPBUnit->getFrame()->getBotFieldPoc() );
else m_pcCurrDPBUnit->getFrame()->setPoc( m_pcCurrDPBUnit->getFrame()->getTopFieldPoc() );
m_pcCurrDPBUnit->setPicType( PicType ( FRAME ^ eCurrentPicType ) );
m_cUsedDPBUnitList.push_back( m_pcCurrDPBUnit );
bCurrUnitAdded = true;
}
//----- generate decreasing POC list -----
for( Int iMaxPoc = iCurrPoc; true; )
{
DPBUnit* pNext = NULL;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() &&
(*iter)->getFrame()->getPoc() < iMaxPoc &&
( !pNext || (*iter)->getFrame()->getPoc() > pNext->getFrame()->getPoc() ) &&
(*iter)->isBaseRep() == bBaseRep )
{
pNext = (*iter);
}
}
if( !pNext )
{
break;
}
iMaxPoc = pNext->getFrame()->getPoc();
RNOK( cDecreasingPocList.add( pNext->getFrame() ) );
}
//----- generate increasing POC list -----
for( Int iMinPoc = iCurrPoc; true; )
{
DPBUnit* pNext = NULL;
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() &&
(*iter)->getFrame()->getPoc() > iMinPoc &&
( ! pNext || (*iter)->getFrame()->getPoc() < pNext->getFrame()->getPoc() ) &&
(*iter)->isBaseRep() == bBaseRep )
{
pNext = (*iter);
}
}
if( !pNext )
{
break;
}
iMinPoc = pNext->getFrame()->getPoc();
RNOK( cIncreasingPocList.add( pNext->getFrame() ) );
}
//----- list 0 and list 1 -----
UInt uiPos;
for( uiPos = 0; uiPos < cDecreasingPocList.getSize(); uiPos++ )
{
RNOK( rcList0.add( cDecreasingPocList.getEntry( uiPos ) ) );
}
for( uiPos = 0; uiPos < cIncreasingPocList.getSize(); uiPos++ )
{
RNOK( rcList0.add( cIncreasingPocList.getEntry( uiPos ) ) );
RNOK( rcList1.add( cIncreasingPocList.getEntry( uiPos ) ) );
}
for( uiPos = 0; uiPos < cDecreasingPocList.getSize(); uiPos++ )
{
RNOK( rcList1.add( cDecreasingPocList.getEntry(uiPos) ) );
}
if( eCurrentPicType!=FRAME )
{
RNOK( xSetInitialRefFieldList( rcList0, pcCurrentFrame, eCurrentPicType, eSliceType ) );
RNOK( xSetInitialRefFieldList( rcList1, pcCurrentFrame, eCurrentPicType, eSliceType ) );
}
//----- check for element switching -----
if( rcList1.getActive() >= 2 && rcList0.getActive() == rcList1.getActive() )
{
Bool bSwitch = true;
for( uiPos = 0; uiPos < rcList1.getActive(); uiPos++ )
{
if( rcList0.getEntry(uiPos) != rcList1.getEntry(uiPos) )
{
bSwitch = false;
break;
}
}
if( bSwitch )
{
rcList1.switchFirst();
}
}
if( bCurrUnitAdded )
{
m_cUsedDPBUnitList.pop_back();
m_pcCurrDPBUnit->getFrame()->setPoc( iCurrFramePoc );
m_pcCurrDPBUnit->setPicType( FRAME );
}
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xPrdListRemapping ( RefFrameList& rcList,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -