📄 extractor.cpp
字号:
auiQLRate[ MAX_QLAYERS - 1 - ( ( uiQId - 1 ) << 3 ) - uiTId ] = aauiTLRate[uiTId][uiQId];
}
}
//===== accumulate rate =====
for( uiQId = MAX_QLAYERS + 1; uiQId > 0; uiQId-- )
{
auiQLRate[uiQId-1] += auiQLRate[uiQId];
}
//===== reset input file =====
RNOKS( static_cast<ReadBitstreamFile*>( m_pcReadBitstream )->uninit() );
RNOKS( static_cast<ReadBitstreamFile*>( m_pcReadBitstream )->init ( m_pcExtractorParameter->getInFile() ) );
return Err::m_nOK;
}
ErrVal
Extractor::xExtract( UInt uiTargetLayer,
Bool bQualityLayerPresent,
Int iQualityLayer,
UInt& ruiInLayerRate,
Bool bNoSpecialFirstFrame )
{
Bool bEOS = false;
Bool bNextIsSuffix = false;
BinData* pcBinData = 0;
UInt uiDId = 0;
UInt uiTId = 0;
UInt uiQId = 0;
UInt uiPId = 0;
UInt uiPacketSize = 0;
UInt uiNumAVCPics = 0;
h264::SEI::SEIMessage* pcScalableSei = 0;
h264::PacketDescription cPacketDescription;
//===== initialize and read scalable SEI message =====
{
//----- init -----
RNOK( m_pcH264AVCPacketAnalyzer ->init () );
//----- read first packet, which must contain the scalable SEI -----
RNOK( m_pcReadBitstream ->extractPacket ( pcBinData, bEOS ) );
ROT ( bEOS );
RNOK( m_pcH264AVCPacketAnalyzer ->process ( pcBinData, cPacketDescription, pcScalableSei ) );
ROF ( pcScalableSei );
//----- delete SEI -----
delete pcScalableSei;
pcScalableSei = 0;
//----- get packet size -----
while( pcBinData->data()[ pcBinData->size() - 1 ] == 0x00 )
{
RNOK( pcBinData->decreaseEndPos( 1 ) ); // remove zero at end
}
//----- write and release packet -----
RNOK( m_pcWriteBitstream ->writePacket ( &m_cBinDataStartCode ) );
RNOK( m_pcWriteBitstream ->writePacket ( pcBinData ) );
RNOK( m_pcReadBitstream ->releasePacket ( pcBinData ) );
pcBinData = 0;
}
//===== MAIN LOOP OVER PACKETS =====
while( ! bEOS )
{
//===== get packet =====
RNOK ( m_pcReadBitstream->extractPacket( pcBinData, bEOS ) );
if ( bEOS )
{
RNOK( m_pcReadBitstream->releasePacket( pcBinData ) );
pcBinData = NULL;
continue;
}
//===== get packet description =====
RNOK( m_pcH264AVCPacketAnalyzer->process( pcBinData, cPacketDescription, pcScalableSei ) );
ROT ( pcScalableSei );
ROT ( cPacketDescription.ApplyToNext );
//===== get packet size =====
while( pcBinData->data()[ pcBinData->size() - 1 ] == 0x00 )
{
RNOK( pcBinData->decreaseEndPos( 1 ) ); // remove zero at end
}
//==== get parameters =====
{
uiPacketSize = 4 + pcBinData->size();
uiDId = cPacketDescription.Layer;
//prefix unit{{
if(cPacketDescription.NalUnitType != NAL_UNIT_CODED_SLICE && cPacketDescription.NalUnitType != NAL_UNIT_CODED_SLICE_IDR)
uiTId = cPacketDescription.Level;
//prefix unit}}
uiQId = cPacketDescription.FGSLayer;
uiPId = cPacketDescription.uiPId;
//----- check whether next NAL unit is a suffix NAL unit -----
if( cPacketDescription.NalUnitType == NAL_UNIT_CODED_SLICE ||
cPacketDescription.NalUnitType == NAL_UNIT_CODED_SLICE_IDR )
{
Int iStreamPos = 0;
h264::SEI::SEIMessage* pcScalableSeiTemp = 0;
BinData* pcBinDataTemp = 0;
h264::PacketDescription cPacketDescriptionTemp;
RNOK( m_pcReadBitstream ->getPosition ( iStreamPos ) );
RNOK( m_pcReadBitstream ->extractPacket ( pcBinDataTemp, bEOS ) );
ROT ( bEOS );
RNOK( m_pcH264AVCPacketAnalyzer ->process ( pcBinDataTemp, cPacketDescriptionTemp, pcScalableSeiTemp ) );
ROT ( pcScalableSeiTemp );
if ((cPacketDescriptionTemp.NalUnitType == NAL_UNIT_CODED_SLICE_SCALABLE ||
cPacketDescriptionTemp.NalUnitType == NAL_UNIT_CODED_SLICE_IDR_SCALABLE ) &&
cPacketDescriptionTemp.Layer == 0 &&
cPacketDescriptionTemp.FGSLayer == 0 )
{
bNextIsSuffix = true;
uiTId = cPacketDescriptionTemp.Level;
}
//----- increment number of AVC slices -----
if( cPacketDescription.uiFirstMb == 0 )
{
uiNumAVCPics++;
}
//----- release packet and reset stream -----
if( pcBinDataTemp )
{
RNOK( m_pcReadBitstream->releasePacket( pcBinDataTemp ) );
pcBinDataTemp = 0;
}
RNOK ( m_pcReadBitstream->setPosition ( iStreamPos ) );
}
else if( bNextIsSuffix )
{
bNextIsSuffix = false;
}
}
ROT( uiDId > uiTargetLayer );
ROF( uiPId < MAX_QLAYERS );
//===== determine whether packet is kept =====
Bool bKeep = true;
if( uiDId == uiTargetLayer && uiQId > 0 )
{
//---- get quality layer when not present -----
if( ! bQualityLayerPresent )
{
uiPId = MAX_QLAYERS - 1 - ( ( uiQId - 1 ) << 3 ) - uiTId;
}
if( uiQId == 1 && uiNumAVCPics == 1 && ! bNoSpecialFirstFrame)
{
uiPId = MAX_QLAYERS;
}
//---- check whether packet is discarded ----
if( (Int)uiPId < iQualityLayer )
{
bKeep = false;
}
else if( (Int)uiPId == iQualityLayer )
{
if( ruiInLayerRate >= uiPacketSize )
{
ruiInLayerRate -= uiPacketSize;
}
else
{
bKeep = false;
}
}
}
//===== write packet ====
if( bKeep )
{
RNOK( m_pcWriteBitstream->writePacket( &m_cBinDataStartCode ) );
RNOK( m_pcWriteBitstream->writePacket( pcBinData ) );
}
//===== release packet =====
if( pcBinData )
{
RNOK( m_pcReadBitstream->releasePacket( pcBinData ) );
pcBinData = NULL;
}
} // end of while( ! bEOS )
//===== uninit =====
RNOK( m_pcH264AVCPacketAnalyzer->uninit() );
return Err::m_nOK;
}
// Keep ROI NAL ICU/ETRI DS
Int Extractor::CurNalKeepingNeed(h264::PacketDescription cPacketDescription
, const ExtractorParameter::Point& rcExtPoint)
{
Bool bIsDataNal = false;
if (
(1 <= cPacketDescription.NalUnitType && cPacketDescription.NalUnitType <= 5)
|| (cPacketDescription.NalUnitType == 20 || cPacketDescription.NalUnitType == 21)
)
{
bIsDataNal = true;
}
Int iExtactionROINum = m_pcExtractorParameter->getExtractedNumROI();
Bool bROIFlag = m_pcExtractorParameter->getROIFlag();
int keepingNAL = -1;
if( bROIFlag == true && bIsDataNal == true )
{
for(int i=0; i<iExtactionROINum; i++)
{
Int SG_ID =-1;
for(int sg_id=0;sg_id<8;sg_id++)
{
if(cPacketDescription.uiFirstMb == m_pcH264AVCPacketAnalyzer->uiaAddrFirstMBofROIs[cPacketDescription.PPSid][sg_id])
{
SG_ID=sg_id;
break;
}
} // end for check sg (until 8)
Int iROI_ID = getROI_ID(cPacketDescription.Layer,SG_ID);
if(iROI_ID !=-1 &&rcExtPoint.uiROI[i] ==iROI_ID )
{
keepingNAL = 1;
}
if( keepingNAL == 1 )
break;
} // end for
} // end if (bROIFlag == true.. )
else
return true;
return (keepingNAL == 1);
}
ErrVal
Extractor::xExtractPoints()
{
UInt uiNumInput = 0;
UInt uiNumKept = 0;
UInt uiNumCropped = 0;
Bool bKeep = false;
Bool bApplyToNext = false;
Bool bEOS = false;
Bool bCrop = false;
UInt uiLayer = 0;
UInt uiLevel = 0;
UInt uiFGSLayer = 0;
UInt uiPacketSize = 0;
UInt uiShrinkSize = 0;
// JVT-T073 {
Bool bNextSuffix = false;
// JVT-T073 }
UInt uiWantedScalableLayer = GetWantedScalableLayer();
UInt uiWantedLayer = m_pcExtractorParameter->getLayer();
UInt uiWantedLevel = m_pcExtractorParameter->getLevel();
Double dWantedFGSLayer = (Double) m_uiTruncateFGSLayer;
Bool bNewPicture = false;
Bool bFirstPacket = true;
UInt uiCurrFrame = 0; //for both QLAssigner and DeadSubstream
//QLAssigner parameters
Double totalPackets = 0;
Bool bQualityLevelSEI = false;
Double dTot = 0;
UInt uiSEI = 0;
UInt uiSEISize = 0;
UInt uiTotalSEI = 0;
//prefix unit{{
BinData* pcBinData_prefix = NULL;
Bool bDiscardable_prefix;
//prefix unit}}
//DS parameters, count number of frame per layer
Int currFrame[MAX_LAYERS];
for(uiLayer = 0; uiLayer < MAX_LAYERS; uiLayer++)
{
currFrame[uiLayer] = 0;
}
// consider ROI ICU/ETRI DS
const MyList<ExtractorParameter::Point>& rcExtList = m_pcExtractorParameter->getExtractionList();
ROT( rcExtList.size() != 1 );
MyList<ExtractorParameter::Point>::const_iterator cIter = rcExtList.begin ();
MyList<ExtractorParameter::Point>::const_iterator cEnd = rcExtList.end ();
const ExtractorParameter::Point& rcExtPoint = *cIter;
Int Count = 0;
printf("\n\n============Extraction Information======");
printf("\nExtracted spatail layer : %dx%d", rcExtPoint.uiWidth, rcExtPoint.uiHeight);
printf("\nExtracted temporal rate : %2.0ff/s", rcExtPoint.dFrameRate);
RNOK( m_pcH264AVCPacketAnalyzer->init() );
while( ! bEOS )
{
//=========== get packet ===========
BinData* pcBinData = NULL;
// JVT-S080 LMI {
BinData * pcBinDataSEILysNotPreDepChange;
ROT( NULL == ( pcBinDataSEILysNotPreDepChange = new BinData ) );
Bool bWriteBinDataSEILysNotPreDepChange = false;
Bool bWriteBinData = true;
// JVT-S080 LMI }
RNOK( m_pcReadBitstream->extractPacket( pcBinData, bEOS ) );
if( bEOS )
{
RNOK( m_pcReadBitstream->releasePacket( pcBinData ) );
pcBinData = NULL;
//TMM_FIX {
RNOK( m_pcReadBitstream->releasePacket( pcBinDataSEILysNotPreDepChange ) );
pcBinDataSEILysNotPreDepChange = NULL;
//TMM_FIX }
continue;
}
//========== get packet description ==========
h264::SEI::SEIMessage* pcScalableSEIMessage = 0;
h264::PacketDescription cPacketDescription;
RNOK( m_pcH264AVCPacketAnalyzer->process( pcBinData, cPacketDescription, pcScalableSEIMessage ) );
//prefix unit{{
if(cPacketDescription.NalUnitType == 14)
{
if(pcBinData_prefix)
RNOK( m_pcReadBitstream->releasePacket( pcBinData_prefix ) );
bDiscardable_prefix = cPacketDescription.bDiscardable;
pcBinData_prefix = pcBinData;
uiLevel = cPacketDescription.Level;
continue;
}
//prefix unit}}
if( pcScalableSEIMessage ) //re-write scalability SEI message
{
bFirstPacket = true;
// JVT-S080 LMI {
if( pcScalableSEIMessage->getMessageType() == h264::SEI::SCALABLE_SEI || pcScalableSEIMessage->getMessageType() == h264::SEI::SCALABLE_SEI_LAYERS_NOT_PRESENT || pcScalableSEIMessage->getMessageType() == h264::SEI::SCALABLE_SEI_DEPENDENCY_CHANGE )
{
if( pcScalableSEIMessage->getMessageType() != h264::SEI::SCALABLE_SEI )
bWriteBinData = false;
RNOK( xChangeScalableSEIMesssage( pcBinData, pcBinDataSEILysNotPreDepChange, pcScalableSEIMessage, MSYS_UINT_MAX,//uiKeepScalableLayer,
uiWantedScalableLayer, uiWantedLayer, uiWantedLevel, dWantedFGSLayer , MSYS_UINT_MAX ) );
if( pcScalableSEIMessage->getMessageType() == h264::SEI::SCALABLE_SEI )
{
h264::SEI::ScalableSeiLayersNotPresent* pcScalableSeiLayersNotPresent = ( h264::SEI::ScalableSeiLayersNotPresent*) pcScalableSEIMessage;
bWriteBinDataSEILysNotPreDepChange = pcScalableSeiLayersNotPresent->getOutputFlag();
}
if( pcScalableSEIMessage->getMessageType() == h264::SEI::SCALABLE_SEI_LAYE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -