📄 gopdecoder.cpp
字号:
ListIdx eListIdx,
SliceHeader* pcSliceHeader )
{
ROTRS( 0 == rcList.getSize(), Err::m_nOK );
ROF( pcSliceHeader );
const RefPicListReOrdering& rcRplrBuffer = pcSliceHeader->getRefPicListReordering( eListIdx );
//===== re-odering =====
if( rcRplrBuffer.getRefPicListReorderingFlag() )
{
const PicType eCurrentPicType = pcSliceHeader->getPicType();
UInt uiPicNumPred = ( eCurrentPicType==FRAME ? pcSliceHeader->getFrameNum() :
pcSliceHeader->getFrameNum()*2+1 );
UInt uiMaxPicNum = ( eCurrentPicType==FRAME ? m_uiMaxFrameNum : 2*m_uiMaxFrameNum );
Bool bBaseRep = pcSliceHeader->getUseRefBasePicFlag();
UInt uiIndex = 0;
ReOrderingOfPicNumsIdc uiCommand;
UInt uiIdentifier = 0;
while( RPLR_END != ( uiCommand = rcRplrBuffer.get(uiIndex).getCommand(uiIdentifier) ) )
{
Frame* pcFrame = NULL;
if( uiCommand == RPLR_LONG )
{
//===== long term index =====
RERR(); // long-term indices are currently not supported by the software
}
else
{
//===== short term index =====
UInt uiAbsDiff = uiIdentifier + 1;
//----- set short-term index (pic num) -----
if( uiCommand == RPLR_NEG )
{
if( uiPicNumPred < uiAbsDiff )
{
uiPicNumPred -= ( uiAbsDiff - uiMaxPicNum );
}
else
{
uiPicNumPred -= uiAbsDiff;
}
}
else // uiCommand == RPLR_POS
{
if( uiPicNumPred + uiAbsDiff > uiMaxPicNum - 1 )
{
uiPicNumPred += ( uiAbsDiff - uiMaxPicNum );
}
else
{
uiPicNumPred += uiAbsDiff;
}
}
uiIdentifier = uiPicNumPred;
PicType ePicType;
xSetIdentifier( uiIdentifier, ePicType, eCurrentPicType );
//----- get frame -----
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter)->isNeededForRef() &&
(*iter)->getFrameNum() == uiIdentifier &&
(!pcFrame || (*iter)->isBaseRep() == bBaseRep ) )
{
pcFrame = (*iter)->getFrame()->getPic( ePicType );
}
}
if( !pcFrame )
{
fprintf( stderr, "\nERROR: MISSING PICTURE !!!!\n\n");
RERR();
}
//----- find picture in reference list -----
UInt uiRemoveIndex = MSYS_UINT_MAX;
for( UInt uiPos = uiIndex; uiPos < rcList.getActive(); uiPos++ ) // active is equal to size !!!
{
if( rcList.getEntry( uiPos ) == pcFrame )
{
uiRemoveIndex = uiPos;
break;
}
}
//----- reference list re-ordering -----
RNOK( rcList.setElementAndRemove( uiIndex, uiRemoveIndex, pcFrame ) );
uiIndex++;
} // short-term RPLR
} // while command
}
//===== set final size =====
//EIDR JVT-Q065
// ROT( pcSliceHeader->getNumRefIdxActive( eListIdx ) > rcList.getActive() );
rcList.setActive( pcSliceHeader->getNumRefIdxActive( eListIdx ) );
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::xDumpRefList( RefFrameList& rcList,
ListIdx eListIdx)
{
#if 1 // NO_DEBUG
return Err::m_nOK;
#endif
printf("LIST_%d={", eListIdx );
for( UInt uiIndex = 1; uiIndex <= rcList.getActive(); uiIndex++ )
{
const PicType ePicType = rcList[uiIndex]->getPicType();
printf(" %s POC=%4d,", ePicType==FRAME ? "FRAME" : ( ePicType==TOP_FIELD ? "TOP_FIELD" : "BOT_FIELD" ), rcList[uiIndex]->getPoc() );
}
printf(" }\n");
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::initPicCurrDPBUnit( PicBuffer*& rpcPicBuffer,
Bool bRef)
{
ROF( m_bInitDone );
if( ! bRef )
{
//===== insert pic buffer in list =====
m_cPicBufferList.push_back( rpcPicBuffer );
rpcPicBuffer = 0;
}
m_pcCurrDPBUnit->getCtrlData().clear();
m_pcCurrDPBUnit->getCtrlData().getMbDataCtrl()->reset();
m_pcCurrDPBUnit->getCtrlData().getMbDataCtrl()->clear();
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::initCurrDPBUnit( DPBUnit*& rpcCurrDPBUnit,
SliceHeader* pcSliceHeader,
PicBufferList& rcOutputList,
PicBufferList& rcUnusedList,
Bool bFirstSliceInLayerRepresentation )
{
ROF( m_bInitDone );
Bool bNewFrame = true;
if( NULL != m_pcLastDPBUnit )
{
bNewFrame = ! pcSliceHeader->isFieldPair( m_pcLastDPBUnit->getFrameNum(), m_pcLastDPBUnit->getPicType(), m_pcLastDPBUnit->isNalRefIdc() );
}
if( ! bNewFrame )
{
// reuse the DPBUnit in case of second field
m_cFreeDPBUnitList.push_back( m_pcCurrDPBUnit );
DPBUnitList::iterator iter = m_cUsedDPBUnitList.find( m_pcLastDPBUnit );
if( iter != m_cUsedDPBUnitList.end() )
{
m_cUsedDPBUnitList.erase( iter );
}
m_pcCurrDPBUnit = m_pcLastDPBUnit;
}
if( pcSliceHeader->getQualityId() == 0 && bFirstSliceInLayerRepresentation && bNewFrame )
{
//===== check missing pictures =====
RNOK( xCheckMissingPics( pcSliceHeader, rcOutputList, rcUnusedList ) );
}
//===== initialize current DPB unit =====
RNOK( m_pcCurrDPBUnit->init( *pcSliceHeader ) );
ROT( pcSliceHeader->getUseRefBasePicFlag() && !pcSliceHeader->getNalRefIdc() ); // just a check
m_pcCurrDPBUnit->getCtrlData().setSliceHeader( pcSliceHeader );
if( bFirstSliceInLayerRepresentation )
{
if( bNewFrame )
{
m_pcCurrDPBUnit->setPicType( pcSliceHeader->getPicType() );
}
else
{
m_pcCurrDPBUnit->setPicType( FRAME );
}
}
m_pcCurrDPBUnit->setNalRefIdc( pcSliceHeader->getNalRefIdc() );
//===== set DPB unit =====
rpcCurrDPBUnit = m_pcCurrDPBUnit;
m_pcLastDPBUnit = m_pcCurrDPBUnit;
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::clear( PicBufferList& rcOutputList,
PicBufferList& rcUnusedList )
{
RNOK( xClearOutputAll( rcOutputList, rcUnusedList, true ) ); // clear and output all pictures
ROF ( m_cPicBufferList.empty() );
return Err::m_nOK;
}
DPBUnit*
DecodedPicBuffer::getLastUnit()
{
ROTRS( m_cUsedDPBUnitList.empty(), 0 );
return m_cUsedDPBUnitList.back();
}
ErrVal
DecodedPicBuffer::setPrdRefLists( DPBUnit* pcCurrDPBUnit )
{
ROF( m_pcCurrDPBUnit == pcCurrDPBUnit );
ROF( m_pcCurrDPBUnit->getCtrlData().getSliceHeader() );
SliceHeader* pcSliceHeader = m_pcCurrDPBUnit->getCtrlData().getSliceHeader();
ROF( pcSliceHeader );
const PicType ePicType = pcSliceHeader->getPicType ();
const SliceType eSliceType = pcSliceHeader->getSliceType();
RefFrameList& rcList0 = m_pcCurrDPBUnit->getCtrlData().getPrdFrameList( LIST_0 );
RefFrameList& rcList1 = m_pcCurrDPBUnit->getCtrlData().getPrdFrameList( LIST_1 );
MbDataCtrl* pcMbDataCtrl0L1 = 0;
Frame* pcCurrentFrame = m_pcCurrDPBUnit->getFrame();
if( pcSliceHeader->isIntraSlice() )
{
}
else if( pcSliceHeader->isPSlice() )
{
RNOK( xInitPrdListPSlice( rcList0, pcCurrentFrame, ePicType, eSliceType ) );
RNOK( xPrdListRemapping ( rcList0, LIST_0, pcSliceHeader ) );
RNOK( xDumpRefList ( rcList0, LIST_0 ) );
}
else
{
RNOK( xInitPrdListsBSlice( rcList0, rcList1, pcCurrentFrame, ePicType, eSliceType ) );
RNOK( xPrdListRemapping ( rcList0, LIST_0, pcSliceHeader ) );
RNOK( xPrdListRemapping ( rcList1, LIST_1, pcSliceHeader ) );
RNOK( xDumpRefList ( rcList0, LIST_0 ) );
RNOK( xDumpRefList ( rcList1, LIST_1 ) );
if( pcSliceHeader->isH264AVCCompatible() )
{
const Frame* pcFrame0L1 = rcList1[1];
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin ();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
DPBUnit* pcDPBUnit = (*iter);
Frame* pcFrame = pcDPBUnit->getFrame()->getPic( pcFrame0L1->getPicType() );
MbDataCtrl* pcMbDataCtrl = pcDPBUnit->getMbDataCtrlBL();
if( pcFrame == pcFrame0L1 )
{
pcMbDataCtrl0L1 = pcMbDataCtrl;
}
}
ROF( pcMbDataCtrl0L1 );
}
}
m_pcCurrDPBUnit->getCtrlData().setMbDataCtrl0L1( pcMbDataCtrl0L1 );
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::store( DPBUnit*& rpcDPBUnit,
PicBufferList& rcOutputList,
PicBufferList& rcUnusedList,
Frame* pcFrameBaseRep )
{
Bool bRef = ( rpcDPBUnit->getCtrlData().getSliceHeader()->getQualityId() > 0 );
if( rpcDPBUnit->isNeededForRef() || rpcDPBUnit->getCtrlData().getSliceHeader()->getOutputFlag() )
{
RNOK( xStorePicture( rpcDPBUnit, rcOutputList, rcUnusedList,
rpcDPBUnit->getCtrlData().getSliceHeader()->getIdrFlag(),
rpcDPBUnit->getCtrlData().getSliceHeader()->getSPS().getFrameMbsOnlyFlag(), bRef ) );
if( !rpcDPBUnit->getCtrlData().getSliceHeader()->getOutputFlag() )
{
rpcDPBUnit->markOutputted();
}
}
if( rpcDPBUnit->isNeededForRef() )
{
m_uiLastRefFrameNum = rpcDPBUnit->getFrameNum();
}
ROFRS( pcFrameBaseRep, Err::m_nOK );
ROTRS( bRef, Err::m_nOK );
// Do not store the base representation if not specified in the stream
ROFRS( rpcDPBUnit->getCtrlData().getSliceHeader()->getStoreRefBasePicFlag(), Err::m_nOK );
//===== store base representation =====
//--- get DPB unit ---
if( m_cFreeDPBUnitList.empty() )
{
// not sure whether this always works ...
RNOK( xOutput( rcOutputList, rcUnusedList ) );
}
DPBUnit* pcBaseRep = NULL;
DPBUnitList::iterator iter1 = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end1 = m_cUsedDPBUnitList.end ();
for( ; iter1 != end1; iter1++ )
{
if( ((*iter1)->getFrameNum() == rpcDPBUnit->getFrameNum() ) &&
( (*iter1)->isBaseRep ()))
{
pcBaseRep = (*iter1);
m_cUsedDPBUnitList.erase( iter1 );
break;
}
}
if( NULL == pcBaseRep )
{
pcBaseRep = m_cFreeDPBUnitList.popFront();
}
//--- init unit and extend picture ---
const PicType ePicType = rpcDPBUnit->getCtrlData().getSliceHeader()->getPicType();
const Bool bFrameMbsOnlyFlag = rpcDPBUnit->getCtrlData().getSliceHeader()->getSPS().getFrameMbsOnlyFlag();
RNOK( pcBaseRep->initBase( *rpcDPBUnit, pcFrameBaseRep ) );
RNOK( m_pcYuvBufferCtrl->initMb() );
RNOK( pcBaseRep->getFrame()->extendFrame( NULL, ePicType, bFrameMbsOnlyFlag ) );
if( !bRef )
{
//--- store just before normal representation of the same picture
DPBUnitList::iterator iter = m_cUsedDPBUnitList.begin();
DPBUnitList::iterator end = m_cUsedDPBUnitList.end ();
for( ; iter != end; iter++ )
{
if( (*iter) == rpcDPBUnit )
{
break;
}
}
ROT( iter == end );
m_cUsedDPBUnitList.insert( iter, pcBaseRep );
RNOK( xDumpDPB() );
//===== reset DPB unit =====
rpcDPBUnit = 0;
}
return Err::m_nOK;
}
ErrVal
DecodedPicBuffer::update( DPBUnit* pcDPBUnit )
{
ROF( pcDPBUnit );
//---- fill border ----
RNOK( m_pcYuvBufferCtrl->initMb() );
const PicType ePicType = pcDPBUnit->getCtrlData().getSliceHeader()->getPicType();
const Bool bFrameMbsOnlyFlag = pcDPBUnit->getCtrlData().getSliceHeader()->getSPS().getFrameMbsOnlyFlag();
RNOK( pcDPBUnit->getFrame()->extendFrame( NULL, ePicType, bFrameMbsOnlyFlag ) );
return Err::m_nOK;
}
MbStatus::MbStatus()
: m_uiSliceIdc ( MSYS_UINT_MAX )
, m_bIsCoded ( false )
, m_pcSliceHeader ( 0 )
{
}
MbStatus::~MbStatus()
{
}
Void
MbStatus::reset()
{
m_uiSliceIdc = MSYS_UINT_MAX;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -